React Native createContext() and useContext() returning null

Viewed 40

I have tried looking at other posts with similar errors but I can't manage to find one that makes it work as expected.

AuthContext.js

import React from "react";

const AuthContext = React.createContext();
export default AuthContext;

const AuthContextProvider = ({ children }) => {
    const authContext = React.useMemo(
        () => ({
          signIn: async (data) => {
            await AsyncStorage.setItem('userToken', data.token);
            await AsyncStorage.setItem('user', JSON.stringify(data));
            dispatch({type: 'SIGN_IN', token: data.token, user: data});
          },
          signOut: async () => {
            await AsyncStorage.removeItem('userToken');
            await AsyncStorage.removeItem('user');
            dispatch({type: 'SIGN_OUT'});
          }
        }),
        []
      );
    return (
      <AuthContext.Provider
        value={{
          authContext
        }}
      >
        {children}
      </AuthContext.Provider>
    );
  };

Then in App.js

import { AuthContextProvider } from './AuthContext';

....

  return (
    <PaperProvider theme={theme}>
      <AuthContextProvider>
        <SafeAreaProvider>
          <NavigationContainer>
           <DetailsScreen />
          </NavigationContainer>
        </SafeAreaProvider>
      </AuthContextProvider>
    </PaperProvider>
  );

Then in DetailsScreen.js

import { AuthContext } from "../AuthContext";

constructor(props) {
    const {context} = useContext(AuthContext);
    console.log("-----------------------------", context); // returns undefined
    super(props, context);
  }

The error this block of code is causing is:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

I am out of ideas as to what could be wrong.

1 Answers

The context AuthContext that you created in AuthContext.js exports the context as default, but you import it as named-import, ie using import {} from. So the useContext hook takes as an argument a null instead of the actual context created by React.createContext()

Then be careful that const {context} = useContext(AuthContext); is also wrong as the hook will return the object {authContext: {...}} which means that you have to do const {authContext} = useContext(AuthContext);

In the Provider you can avoid passing value={{authContext}} and instead pass value={authContext} then you can just const authContext = useContext(AuthContext);

Related