I'm attempting to use the modern Context API within React-Native, but I'm getting the following error:
TypeError: TypeError: undefined is not an object (evaluating 'Context._context')
my createDataContext.js:
import React, { useReducer } from 'react'
export default (reducer, actions, defaultValue) => {
const Context = React.createContext()
const Provider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, defaultValue)
const boundActions = {}
for (let key in actions) {
boundActions[key] = actions[key](dispatch)
}
return (
<Context.Provider value={{ state, ...boundActions }}>
{children}
</Context.Provider>
)
}
return { Context, Provider }
}
My context.js:
import { AsyncStorage } from 'react-native'
import createDataContext from './createDataContext'
import {
LOGIN_FIRST_STEP,
LOGIN_SECOND_STEP,
AUTH_MODAL,
SIGNIN_MODAL,
SIGNUP_MODAL,
} from '../constants'
const INITIAL_STATE = {
email: '',
firstName: '',
lastName: '',
password: '',
cardNumber: '',
expiration: '',
CVV: '',
billingAddress: '',
authOpen: false,
signupOpen: false,
signinOpen: false,
}
const reducer = (state = INITIAL_STATE, { type, payload }) => {
switch (type) {
case LOGIN_FIRST_STEP:
const { email, firstName, lastName, password } = payload
return {
...state,
email,
firstName,
lastName,
password,
}
case LOGIN_SECOND_STEP:
const { cardNumber, expiration, CVV, billingAddress } = payload
return {
...state,
email,
cardNumber,
expiration,
CVV,
billingAddress,
}
case AUTH_MODAL:
return {
...state,
authOpen: true,
signupOpen: false,
signinOpen: false,
}
case SIGNUP_MODAL:
return {
...state,
authOpen: false,
signupOpen: true,
signinOpen: false,
}
case SIGNIN_MODAL:
return {
...state,
authOpen: false,
signupOpen: false,
signinOpen: true,
}
default:
return state
}
}
const login = dispatch => values => {
dispatch({ type: LOGIN_FIRST_STEP, payload: values })
}
const login2 = dispatch => values => {
dispatch({ type: LOGIN_SECOND_STEP, payload: values })
}
const auth = disaptch => () => {
dipatch({ type: AUTH_MODAL })
}
const signin = disaptch => () => {
dipatch({ type: SIGNIN_MODAL })
}
const signup = disaptch => () => {
dipatch({ type: SIGNUP_MODAL })
}
export const { Provider, Context } = createDataContext(
reducer,
{ login, login2, auth, signin, signup },
{ authOpen: false , signinOpen: false, signupOpen: false }
)
package.json:
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"@apollo/react-hooks": "^3.1.1",
"apollo-cache-inmemory": "^1.6.3",
"apollo-client": "^2.6.4",
"apollo-link": "^1.2.13",
"apollo-link-error": "^1.1.12",
"apollo-link-http": "^1.5.16",
"apollo-link-state": "^0.4.2",
"apollo-link-ws": "^1.0.19",
"apollo-utilities": "^1.3.2",
"expo": "^34.0.1",
"formik": "^1.5.8",
"graphql": "^14.5.6",
"graphql-tag": "^2.10.1",
"react": "16.8.3",
"react-apollo": "^3.1.1",
"react-dom": "^16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-34.0.0.tar.gz",
"react-native-gesture-handler": "~1.3.0",
"react-native-maps": "~0.24.0",
"react-native-reanimated": "~1.1.0",
"react-native-web": "^0.11.4",
"react-navigation": "^4.0.6",
"react-navigation-stack": "^1.8.0",
"react-navigation-tabs": "^2.5.4",
"subscriptions-transport-ws": "^0.9.16",
"yup": "^0.27.0"
},
"devDependencies": {
"babel-preset-expo": "^6.0.0"
},
"private": true
}
And finally app.js:
export default App = () => {
return (
<ApolloProvider client={client}>
<ApolloHooksProvider client={client}>
<ContextProvider>
<Root />
</ContextProvider>
</ApolloHooksProvider>
</ApolloProvider>
)
}
When I attempt to use by importing Context
and using the useContext
hook:
const {
state,
authModal
} = useContext(Context)
the aforementioned error shows. I've tried removing the react-native
package and re-installing it with the latest version. I've tried deleting the node modules, clearing the cache, and re-installing them, but none seem to solve the issue.
React Context API provides a easy way to pass data through the component tree without having to pass props down manually at every level. You can find more about the Context API in React documentation. You can use the React Context API with React Native Navigation with a limitation.
The useContext is the React hook, used in context API to consume the context state or object. There are two options for getting the context object. We can get the context object from Context Consumer or useContext Hook. UseContext Hook is an exquisite, more excellent way to get the context object with less code.
If useContext fails to create a context, it'll return undefined because we forgot the wrap our App or component in a ThemeProvider. If everything works fine, we'll return the actual context.
I had the same error and it's because I was importing Context like this:
import {Context} from '...'
INSTEAD OF
import Context from '..'
For me, it was as simple as... I forgot to add the Provider to my main (App.js) file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With