【问题标题】:How can I access my context API state in react app.js file如何在 react app.js 文件中访问我的上下文 API 状态
【发布时间】:2021-06-23 22:20:02
【问题描述】:

您好,我正在使用 Context API 管理我的 react 应用程序状态,并且我能够在我的 app.js 文件之外的所有文件中解构我的 Context 的状态和功能。

在这里,我创建了一个名为“createDataContext”的可重用文件,以防止在为每个 Context 创建 Context 和 Provider 时编写重复代码。

import React, { createContext, useReducer } from 'react';

export default (reducer, actions, initialState) => {
  const Context = createContext();

  const Provider = ({ children }) => {
    const [state, dispatch] = useReducer(reducer, initialState);

    const boundActions = {};
    for(let key in actions){
      boundActions[key] = actions[key](dispatch);
    }

    return (
      <Context.Provider value={{ state, ...boundActions }}>
        { children }
      </Context.Provider>
    )
  }

  return { Context, Provider }
}

这是我使用 createDataContext 文件的 AuthContext

import createDataContext from "./createDataContext";
import api from '../api/api'

const authReducer = (state, action) => {
  switch(action.type){
    case 'signin':
      return { errorMessage: '', token: action.payload };
    case 'add_error':
      return { ...state, errorMessage: action.payload };
    default:
      return state;
  }
}

const login = dispatch => {
  return async (email, password) => {
    try {
      const res = await api.post('/users/login', { email, password });
      localStorage.setItem('token', res.data.token);
      dispatch({ type: 'signin', payload: res.data.token });
    }catch(err){
      dispatch({ type: 'add_error', payload: 'signin failed' })
    }
  }
}

export const { Context, Provider } = createDataContext(authReducer, { login }, {
  token: null,
  errorMessage: ''
});

我可以在我的页面和组件中使用上下文和析构函数关闭状态和功能,但无法在我的 app.js 文件中这样做。

import React, { useContext } from 'react';
import Home from './pages/home/Home';
import Login from './pages/login/Login';
import Profile from './pages/profile/Profile';
import Register from './pages/register/Register';
import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-dom';
import Navbar from './components/navbar/Navbar';
import { Provider as AuthProvider } from './context/AuthContext';
import { Context } from './context/AuthContext';

function App() {
  const { state, login } = useContext(Context);

  return (
    <AuthProvider>
      <Router>
        <Navbar />
        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route path="/login">
            <Login />
          </Route>
          <Route path="/register">
            <Register />
          </Route>
          <Route path="/profile/:id">
            <Profile />
          </Route>
        </Switch>
      </Router>
    </AuthProvider>
  );
}

export default App;

我收到错误 TypeError: Cannot destructure property 'state' of 'Object(...)(...)' 因为它是未定义的。 有人可以指出我是什么或者我要去哪里错了。谢谢。

【问题讨论】:

    标签: javascript reactjs react-context


    【解决方案1】:

    您不能在提供上下文的同一组件中使用上下文。为了解决这个问题,创建另一个新组件,它是 Provider 的其余子级的包装器

    // AppWrapper.jsx
    import React from 'react'
    import App from './app'
    import { Provider as AuthProvider } from './context/AuthContext'
    
    const AppWrapper = () => {
      return (
        <AuthProvider>
          <App />
        </AuthProvider>
      )
    }
    
    default export AppWrapper
    

    然后从您的 app.js 组件中删除 &lt;AuthProvider&gt;,并在树中调用 &lt;App /&gt; 的任何位置改为调用 &lt;AppWrapper /&gt;。然后在应用程序内部,您可以像尝试那样使用上下文。

    【讨论】:

      猜你喜欢
      • 2020-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-28
      • 1970-01-01
      • 2019-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多