在 React Native 中使用 useContext 的上下文 API 显示 TypeError

Posted

技术标签:

【中文标题】在 React Native 中使用 useContext 的上下文 API 显示 TypeError【英文标题】:Context API using useContext in React Native is showing a TypeError 【发布时间】:2020-02-02 07:10:42 【问题描述】:

我正在尝试在 React-Native 中使用现代 Context API,但出现以下错误:

TypeError: TypeError: undefined is not an object (评估 '上下文._上下文')

我的 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 

我的 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

最后是 app.js:

export default App = () => 
  return (
      <ApolloProvider client=client>
          <ApolloHooksProvider client=client>
            <ContextProvider>
              <Root />
            </ContextProvider>
          </ApolloHooksProvider> 
      </ApolloProvider>
  )

当我尝试通过导入Context 并使用useContext 挂钩来使用时:

const 
    state,
    authModal
 = useContext(Context)

上述错误显示。我尝试删除 react-native 包并使用最新版本重新安装它。我已经尝试删除节点模块,清除缓存并重新安装它们,但似乎没有一个可以解决问题。

【问题讨论】:

我也有来自 Stephen Girder 的视频课程的 createDataContext,并且遇到了同样的问题。但我犯的错误是没有用提供者包装根应用程序或父组件....在使用提供者之后它起作用了。 @MohamedIqzas 我用 Provider 包装了根应用程序,仍然得到那个错误:( 【参考方案1】:

我遇到了同样的错误,这是因为我是这样导入上下文的:

从“...”导入 Context

代替

从'..'导入上下文

【讨论】:

我的情况正好相反:我没有使用大括号,而我应该使用大括号。谢谢! 没有帮我解决【参考方案2】:

对我来说,这很简单...我忘记将提供程序添加到我的主 (App.js) 文件中。

【讨论】:

以上是关于在 React Native 中使用 useContext 的上下文 API 显示 TypeError的主要内容,如果未能解决你的问题,请参考以下文章

尝试在 create-react-native-app 项目 (expo) 中使用 react-native-fs

React-native:如何在 React-native 中使用(和翻译)带有 jsx 的 typescript .tsx 文件?

如何在 React Native 中使用 React Native Video 显示多个视频? [关闭]

如何在React Native中使用CreateBottomTabNavigator?

使用 react-native router-flux 时,BackHandler 在 react-native 侧面菜单中不起作用

无法使用 react-native-svg 或 Svg/expo 让 Svg 显示在 react-native 中