Home > Mobile >  Context: Cannot read properties of undefined
Context: Cannot read properties of undefined

Time:05-06

I'm trying to keep a live state of either the user is signed-in or not, so I can either show him or not, specific elements in the components. Using this code it's supposed to console.log(0) and then console.log(1), but it actually throws an error Cannot read properties of undefined.

./addons/Signed.js:

import { useState, createContext } from "react";

export const SignedContext = createContext();

export default function SignedProvider(props) {
  const [SignedIn, setSignedIn] = useState(0);

  return (
    <SignedContext.Provider value={{ SignedIn, setSignedIn }}>
      {props.children}
    </SignedContext.Provider>
  );
}

./screens/Profile.js:

import { useContext } from "react";

import SignedContext from "../addons/Signed";

...

const ProfileScreen = () => {
  const { SignedIn, setSignedIn } = useContext(SignedContext);

  console.log(SignedIn);

  setSignedIn(1);

  console.log(SignedIn);

  ...
}
...

CodePudding user response:

You are using a named export for SignedContext but using a default import in Profile. Thus, you must use curly braces for your import. The following should change your issue.

import { SignedContext } from ".../addons/Signed"

Edit: If ProfileScreen is not a child of SignedContext.Provider, then this will not work. The general workflow is documented here. Hence, if ProfileScreen is not a child of the Provider, the context won't be available to it.

The ususal way to do this, is to define the context provider as a top level element in your app, if you want the context to be available at a global level in your application.

function App = () => {
   const [signedIn, setSignedIn] = useState(0)

   const contextValue = React.useMemo(() => ({signedIn, setSignedIn}), [singedIn])

    // your application structure must be wrapped inside here.
   // as an example I have only used ProfileScreen. 
   // Usually this is your root stack.
   return (
       <SignedContext.Provider value ={contextValue}>
          <ProfileScreen />
       </SignedContext.Provider>
   )
}
  • Related