我正在尝试使用context
处理我的应用程序中的身份验证。我遇到了问题,因为我试图在useContext
之外调用Context.Provider
,所以我将逻辑移到了提供程序的子组件。
现在,我在子组件中调用TypeError: Object is not iterable (cannot read property Symbol(Symbol.iterator))
时收到一条错误消息useContext
。从上下文或其他内容获取值真的是问题吗?
在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;
答案 0 :(得分:1)
我认为这会对您有所帮助。我在上下文中访问数据的解决方案是创建一个自定义钩子。
//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
答案 1 :(得分:1)
如错误所述,Context.Provider
中的authContext.js
不可迭代:
<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);
Voila!您的Context.Provider值是可迭代的,您可以在应用程序中使用它。