我在 React 上遇到异步状态问题
我使用上下文来确定管理员是否经过身份验证并有权访问状态为 isAuth 的页面
interface UserContext {
setToken: (token:string) => void;
getToken: () => string|null;
logout: () => void;
setIsAuth: (value:boolean) => void;
isAuth: boolean;
}
const initialState: UserContext = {
setToken: () => {},
getToken: () => null,
logout: () => {},
setIsAuth: () => {},
isAuth: false,
}
const UserContext = createContext<UserContext>(initialState)
export function UserContextProvider ({children}:{children:React.ReactNode}){
const [isAuth, setIsAuth] = useState(false);
console.log("isAuth in UserContextProvider",isAuth);
const setToken = (token:string) => {
window.localStorage.setItem('token', token);
}
const getToken = () => {
return window.localStorage.getItem('token');
}
const logout = () => {
//redirect("/login")
window.localStorage.removeItem('token');
}
return <UserContext.Provider value={{setToken, getToken, logout, setIsAuth, isAuth }}>
{children}
</UserContext.Provider>
}
export const useUserContext = () => {
return useContext(UserContext)
}
main.ts
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<UserContextProvider>
<App />
</UserContextProvider>
</React.StrictMode>,
)
在应用程序中,我进行 API 调用来检查管理员是否经过身份验证,并将 isAuth 设置为 response.code === 200 (如果经过身份验证,则响应为 200)。在本例中,管理员已通过身份验证,因此响应为 200 并且 isAuth 设置为 true
function App() {
const {setIsAuth,getToken} = useUserContext();
useEffect(() => {
const token = getToken();
fetch(import.meta.env.VITE_API_URL+"/isAuth", {
headers: {Authorization: `Bearer ${token}`}
})
.then((res) => res.json())
.then((response) => {
console.log("response App",response);
setIsAuth(response.code === 200);
})
}, [location.pathname])
在ProjectTable组件(显示项目的管理页面)中,我需要检查他是否通过身份验证,如果没有,则重定向到/login
我做了一个isAuth的日志
export function ProjectTable({projects}:{projects:Project[]}){
const { t } = useTranslation();
const {isAuth} = useUserContext();
const navigateTo = useNavigate();
useEffect(() => {
console.log("isAuth in useEffect ProjectTable",isAuth);
// if (!isAuth){
// navigateTo("/login");
// }
}, [])
这是我在管理页面 ProjectTable 上时的控制台输出,它显示了项目
UserContextProvider 中的 isAuth 为 false,ProjectTable 中的 isAuth 为 false。
然后我进行 API 调用并将 isAuth 设置为 true。
UserContextProvider 中的 isAuth 设置为 true,但 ProjectTable 中未设置。我没有看到表明 isAuth 为 true 的日志;在 UserContextProvider 中的 isAuth 变为 true 之前,我只看到旧日志将其显示为 false。
所以,如果我取消注释 if (!isAuth),我会被重定向到 /login,即使我不应该这样做,因为我已经通过了身份验证
您应该在函数组件中打印
isAuth
。
export function ProjectTable({projects}:{projects:Project[]}){
const {isAuth} = useUserContext();
console.log("isAuth in useEffect ProjectTable",isAuth)
}
或者,将其添加到
useEffect
钩子的依赖列表中
export function ProjectTable({projects}:{projects:Project[]}){
const {isAuth} = useUserContext();
useEffect(() => {
console.log("isAuth in useEffect ProjectTable",isAuth)
}, [isAuth])
}