Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[@types/react] createContext – An argument for 'defaultValue' was not provided. #37023

Closed
alfonmga opened this issue Jul 20, 2019 · 9 comments

Comments

@alfonmga
Copy link

alfonmga commented Jul 20, 2019

Is there any reason of why the argument defaultValue is not optional here?

import * as React from 'react';
import * as firebase from 'firebase/app';

interface AuthProps {
  children: any;
}
interface AuthState {
  user: firebase.User | null;
}
interface AuthContextProps extends AuthState {
  updateUser(user: firebase.User | null): void;
}

export const AuthContext = React.createContext<AuthContextProps>(); // <-- ERROR HERE!

// export const AuthConsumer = AuthContext.Consumer;
export const AuthProvider = (props: AuthProps) => {
  const [state, setState] = React.useState<AuthState>({
    user: null,
  });

  const updateUser = (user: firebase.User | null) => setState({ user });

  return (
    <AuthContext.Provider
      value={{
        updateUser,
        user: state.user,
      }}
    >
      {props.children}
    </AuthContext.Provider>
  );
};

Docs url: https://reactjs.org/docs/context.html#reactcreatecontext

The defaultValue argument is only used when a component does not have a matching Provider above it in the tree.

I have a matching Provider above in the tree, so I should be able to create a context without set a default value or I'm wrong?

@alfonmga
Copy link
Author

I'm closing this issue for now. If someone thinks this is a real issue then be free to contribute.

@nandorojo
Copy link

Not having a default value is keeping my typescript run build from working. Is there any way to make this optional?

@zeekrey
Copy link

zeekrey commented Dec 22, 2019

If you want to compile your code without a default value you can init it with null.

export const AuthContext = React.createContext(null)

@JoshuaKGoldberg
Copy link
Collaborator

JoshuaKGoldberg commented Jan 25, 2020

The null solution no longer works for me. I'll file a new issue.

Edit: no, #34854 mentions why. AH well.

@romenkova
Copy link

romenkova commented Dec 26, 2020

I would also try this:
const AuthContext = React.createContext<AuthContextProps | null>(null) as React.Context<AuthContextProps>;

It looks like a dirty hack that could lead to future problems. But in my case, I have a class instance as a value for the context, so If I pass it as a default value, it initializes 2 times - in the provider's value prop and here.

@VKBobyr
Copy link

VKBobyr commented Jan 11, 2021

The null option is not optimal at all, since you have to do null checks later, but I don't think there's another way, since whatever you're passing into the context is indeed empty for a certain period of time.

@jacksonblankenship
Copy link

I know this thread is old but here's a solution that doesn't require null checks.

interface SomeProps {
  /* your interface */
}

const SomeContext = createContext<SomeProps>(null!);

@antonkarpach
Copy link

What about empty obj?
export const SomeContext = createContext({});

@lucasbasquerotto
Copy link

An empty object will not work if the interface have required fields.

I'm doing a cast while this issue is not solved (if it will ever be):

// instead of:
// export const SomeContext = createContext<SomeProps>({});
export const SomeContext = createContext({} as SomeProps);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants