question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Create context factory function

See original GitHub issue

Do you want to request a feature or report a bug?

feature

React.createContext just returns the value passed in on createContext if there is no provider above in the tree.

Is it possible to get a version that takes in a factory function in the form: createContextFn(fn:() => defaultValue) The factory function will be invoked whenever a default value is needed.

I have two use cases for this.

  • If you want to enforce the usage of a context e.g. :
createContextFn(() => throw new Error("Default value not allowed, Please use FooProvider."))
  • Or you want to use a react hook as a default value:
function useTotal(){
 const [total, setTotal] = useState(0);
 const incFn = () => setTotal(total + 1);
 return {
   total,
   incFn
 };
}


createContextFn(useTotal)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:4
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
dai-shicommented, Dec 23, 2019

can we enforce useContext to throw when it’s used outside <Provider /> ?

How do you like this?

const SomeCtx = React.createContext(new Proxy({}, { get() { throw new Error('...'); } }));

It doesn’t work for primitives though.

0reactions
mwmcodecommented, Dec 23, 2019

Ok… I’m doing the following to make sure it throws when used outside:

  1. initializing to null when creating context,
  2. set context value to initVal inside the provider
  3. so useContext throws when value is null
const AuthCtx = createContext<AuthCtxType | null>(null);

// set init value in the provider
function AuthProvider(props) {
  const [authUser, setUser] = useState<AuthUser>(authUserTemplate); // init val

  useEffect(() => {
    const storageUser = storage.local.getItem(StorageKeys.user);
    const isOnLoginPage = window.location.pathname === '/';

    if (storageUser?.id_token) {
      setUser(storageUser);
      isOnLoginPage && history.push('home'); // TODO: push to user type
    } else {
      history.push('/'); // TODO
    }
  }, [JSON.stringify(authUser)]);
}

export function useAuth(): AuthCtxType {
  const ctx = useContext(AuthCtx);

  if (!ctx) {
    throw new Error('Cannot useAuth() outside <AuthProvider />');
  }
  return ctx;
}

Read more comments on GitHub >

github_iconTop Results From Across the Web

What's the point of React's createContext factory function?
The only use I can think of for having the factory function is declaring a defaultValue that consequent Consumers use - for testing, ......
Read more >
A Guide to React Context and useContext() Hook
const Context = createContext('Default Value');. The factory function accepts one optional argument: the default value.
Read more >
Using the React Context API, the right way (a time saver)
A component factory is a function that returns a React functional component. ... We can use component factories to clean up our codebase...
Read more >
JavaScript Factory Functions
A factory function is a function that returns a new object. Use Object.create() to create an object using an existing object as a...
Read more >
Context Factory in EF Extensions (EFE)
The context factory is a function Func<DbContext, DbContext> that provides the current DbContext as a parameter and require to return a new DbContext....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found