如何将上下文与钩子一起使用进行身份验证?



我正在尝试使用context来处理应用程序中的身份验证片段。我遇到了问题,因为我试图在我的Context.Provider之外调用useContext,所以我将逻辑移动到提供程序的子组件。

现在,我在子组件中调用useContextTypeError: 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
我认为您的问题可能是您已将默认值放在值对象内的数组中。

相关内容

  • 没有找到相关文章

最新更新