Reputation: 2562
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
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
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
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