如何在反应 app.js 文件中访问我的上下文 API 状态
How can I access my context API state in react app.js file
您好,我正在使用 Context API 管理我的 React 应用程序状态,并且我能够在除 app.js 文件之外的所有文件中解构我的 Context 的状态和功能。
我在这里创建了一个名为'createDataContext'的可重用文件,以防止在为每个上下文创建上下文和提供者时编写重复代码。
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 }
}
这是我的 AuthContext,它使用 createDataContext 文件
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: 无法解构 'Object(...)(...)' 的 属性 'state' 因为它未定义。 有人可以指出什么我在或哪里出错了。谢谢。
您不能在提供上下文的同一组件中使用上下文。为了解决这个问题,创建另一个新组件,它是 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 组件中删除 <AuthProvider>
,并且在树中任何调用 <App />
的地方,调用 <AppWrapper />
。然后在应用程序内部,您可以像尝试做的那样使用上下文。
您好,我正在使用 Context API 管理我的 React 应用程序状态,并且我能够在除 app.js 文件之外的所有文件中解构我的 Context 的状态和功能。
我在这里创建了一个名为'createDataContext'的可重用文件,以防止在为每个上下文创建上下文和提供者时编写重复代码。
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 }
}
这是我的 AuthContext,它使用 createDataContext 文件
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: 无法解构 'Object(...)(...)' 的 属性 'state' 因为它未定义。 有人可以指出什么我在或哪里出错了。谢谢。
您不能在提供上下文的同一组件中使用上下文。为了解决这个问题,创建另一个新组件,它是 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 组件中删除 <AuthProvider>
,并且在树中任何调用 <App />
的地方,调用 <AppWrapper />
。然后在应用程序内部,您可以像尝试做的那样使用上下文。