我正在尝试使用context
来处理应用程序中的身份验证片段。我遇到了问题,因为我试图在我的Context.Provider
之外调用useContext
,所以我将逻辑移动到提供程序的子组件。
现在,我在子组件中调用useContext
TypeError: Object is not iterable (cannot read property Symbol(Symbol.iterator))
收到一条错误消息。问题真的是从上下文中获取值还是其他内容?
在app.js
import AuthContextProvider from "./components/context/authContext";
import RegisterRoutes from "./components/routing/registerRoutes";
function App() {
return (
<AuthContextProvider>
<Route
exact
path="/register"
render={(props) => (
<RegisterRoutes {...props} />
)}
/>
</AuthContextProvider>
)
}
在我的authContext.js
import React, { useState, useEffect, createContext } from "react";
export const AuthContext = createContext();
const AuthContextProvider = (props) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const setAuth = (boolean) => {
setIsAuthenticated(boolean);
};
//Auth API logic here//
const apiOptions = {
url: "users/is-verified",
method: "GET",
headers: {
token: localStorage.token,
},
};
async function isAuth() {
axios(apiOptions)
.then((response) => {
const resData = response.data;
resData === true ? setIsAuthenticated(true) : setIsAuthenticated(false);
})
.catch((error) => {
console.log(error.response);
});
}
useEffect(() => {
isAuth();
}, []);
return (
<AuthContext.Provider
value={[isAuthenticated, setIsAuthenticated, setAuth]}
>
{props.children}
</AuthContext.Provider>
);
};
export default AuthContextProvider;
在我的registerRoutes.js
import React, { useContext } from "react";
import { Redirect } from "react-router-dom";
import Register from "../pages/register";
import AuthContext from "../context/authContext";
function RegisterRoutes(props) {
const [isAuthenticated, setAuth] = useContext(AuthContext);
return !isAuthenticated ? (
<Register {...props} setAuth={setAuth} />
) : (
<Redirect to="/login" />
);
}
export default RegisterRoutes;
正如错误所说,authContext.js
值中的Context.Provider
不是可迭代的:
<AuthContext.Provider value={[isAuthenticated, setIsAuthenticated, setAuth]}>
传递给提供程序的值必须是可迭代值(在本例中为有效的 JSON 对象(,而不是您提供的数组。 因此,我们将其更改为:
<AuthContext.Provider value={{isAuthenticated, setIsAuthenticated, setAuth}}>
然后,更改registerRoutes.js
中的引用以正确使用新结构:
const [isAuthenticated, setAuth] = useContext(AuthContext);
成为
const { isAuthenticated, setAuth } = useContext(AuthContext);
瞧!您的 Context.Provider 值是可迭代的,您可以在应用程序中使用它。
我认为这会对你有所帮助。我在上下文中访问数据的解决方案是创建自定义钩子。
//localState.js
import { createContext, useState, useContext } from 'react'
const LocalStateContext = createContext()
const LocalStateProvider = LocalStateContext.Provider
function LocalState({children}) {
const [someState, setSomeState] = useState('')
const defaultValues = {
someState, setSomeState
}
return <LocalStateProvider value={defaultValues}>
{children}
</LocalStateProvider>
}
function useLocalState() {
const all = useContext(LocalStateContext)
return all
}
export {LocalState, LocalStateContext, useLocalState}
使用此代码,可以将整个应用包装在 LocalState 组件中,并使用新的 useLocalState 挂钩访问上下文值。例如
import { useLocalState} from './localstate'
const SomeComponent = () => {
const { someState } = useLocalState()
return (
///...whatever you want
)
}
export default SomeComponent
我认为您的问题可能是您已将默认值放在值对象内的数组中。