Rob Terrell
Rob Terrell

Reputation: 2562

Unable to access Context in app.js react-native

I am currently trying to use context within a react native application. My context code is as follows:

import React, { useState, createContext } from 'react'

export const AuthContext = createContext()

export const AuthProvider = ({ children }) => {
  const [currentUser, setCurrentUser] = useState(null)

return (
    <AuthContext.Provider value={{ currentUser}}>
      {children}
    </AuthContext.Provider>
  )
}

I then import context into my App.js and wrap my App.js in the provider like so:

import React, { useContext } from 'react'
import { AuthProvider, AuthContext } from './src/Context/AuthContext'
other imports etc...

export default function App() {
  const { currentUser } = useContext(AuthContext)
  return (
    <>
      <AuthProvider>
        <IconRegistry icons={EvaIconsPack} />
          <NavigationContainer>
            <RootStackScreen isAuth={false} />
          </NavigationContainer>
      </AuthProvider>
    </>
  )
}

when i try to access currentUser in the app.js I get the following error:

component exception: undefined is not an object, evalauting useContext.currentUser

If I try to access current user in other components of my application; however, I do not receive this error and currentUser console logs to the correct value of null. I am wondering then how I can go about accessing context in app.js. is it possible to wrap a react-native application's index.js in the auth provider? or am i doing something wrong context wise.

version of react-native: 0.63.3 version of react: 16.13.1

Upvotes: 0

Views: 2701

Answers (3)

Koushik Roy
Koushik Roy

Reputation: 1

I just simple wrapped the <App /> in index.js file. Its works good as before.

import App from './App';
import {name as appName} from './app.json';
import AuthProvider from './Components/AuthProvider';

const AppWrapper =()=>{
    return(
        <AuthProvider>
            <App />
        </AuthProvider>
    )
}

AppRegistry.registerComponent(appName, () => AppWrapper);```

Upvotes: 0

Sudarshan
Sudarshan

Reputation: 814

I haven't used the above answer, but I moved AuthContext.Provider to the index.js file and wrapped the App component in it. Now it is working fine for me. I did this because in App.js I have large code due to navigation and routing logic.

Using this we can keep our context logic separated. I used this with React.js and not with ReactNative

ex.

import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import * as serviceWorker from "./serviceWorker";
import "./index.css";
import { AuthProvider } from './src/Context/AuthContext'


ReactDOM.render(
    <AuthProvider>
      <App />
    </AuthProvider>
  document.getElementById("root")
);
serviceWorker.unregister();

Upvotes: 1

Guruparan Giritharan
Guruparan Giritharan

Reputation: 16334

This happening because you are accessing the context outside the provider.

If you check your createContext, you are not providing a default value.

export const AuthContext = createContext(/*No default value*/)

When the useContext is called outside the provider it will use the default value in your case its 'undefined' and it throws an error when you try to access the property currentUser of undefined.

One way to solve this issue is to use the state in app.js file instead of a separate provider component.

export default function App() {
  
  const [currentUser, setCurrentUser] = useState(null);
  const state={currentUser, setCurrentUser};

  return (
    <>
        <AuthContext.Provider value={state}>
        <IconRegistry icons={EvaIconsPack} />
          <NavigationContainer>
            <RootStackScreen isAuth={false} />
          </NavigationContainer>
        </AuthContext.Provider 
    </>
  )
}

This will not have any impact to other components and also you can access the currentUser variable easily just like you access any state.

Upvotes: 2

Related Questions