reactjs - 上下文很慢或被调用两次
问题描述
我用于身份验证的上下文存在问题。如果我在登录时 console.log,首先我得到错误,然后一秒钟后它再次使用令牌等记录。所以,我的代码有问题。
这是我的身份验证钩子:
import { useState, useCallback, useEffect } from "react";
export const useAuth = () => {
const [token, setToken] = useState(false);
const [userId, setUserId] = useState(false);
const login = useCallback((uid, token) => {
setToken(token);
setUserId(uid);
localStorage.setItem(
"userData",
JSON.stringify({
userId: uid,
token: token,
})
);
}, []);
const logout = useCallback(() => {
setToken(null);
setUserId(null);
localStorage.removeItem("userData");
}, []);
useEffect(() => {
const storedData = JSON.parse(localStorage.getItem("userData"));
if (storedData && storedData.token) {
login(storedData.userId, storedData.token);
}
}, [login]);
return { token, login, logout, userId };
};
身份验证上下文:
import { createContext } from "react";
export const AuthContext = createContext({
isLoggedIn: false,
userId: null,
token: null,
login: () => {},
logout: () => {},
});
我遇到问题的组件示例(基本上在我使用此身份验证上下文的所有组件中)
import React, { useContext, useState } from "react";
import AdminCard from "../components/adminCards/AdminCard";
import { AuthContext } from "../../shared/context/auth-context";
const Dashboard = () => {
const auth = useContext(AuthContext);
console.log(auth);
return (
<div className="admin-wrapper">
<div className="main-panel">
<div className="row">
<div className="wrapper">
<div className="col-3">
<AdminCard title="Contact Enquiries" />
<AdminCard title="Card 2" />
<AdminCard title="Card 3" />
</div>
</div>
</div>
</div>
</div>
);
};
export default Dashboard;
在控制台中,我首先看到“false”,然后一秒钟后看到“auth”的内容。
App.js 示例
const App = () => {
const { token, login, logout, userId } = useAuth();
return (
<>
<AuthContext.Provider
value={{
isLoggedIn: !!token,
token: token,
userId: userId,
login: login,
logout: logout,
}}
>
<Router>
<Switch>
<Route path="/" exact>
<Dashboard />
</Route>
</Switch>
</Router>
</AuthContext.Provider>
</>
};
export default App;
问题的一个示例是,如果我通过单击链接登录并导航到仪表板,我没有问题。如果我在仪表板上并刷新浏览器,则会收到 403 错误并且请求失败,因为在发送请求时令牌尚不可用。
useEffect(() => {
const getItems = async () => {
const config = {
method: "get",
url: "http://localhost:8000/api/admin/somedata",
headers: { Authorization: "Bearer " + auth.token },
};
const responseData = await Axios(config);
setItems(responseData.data);
console.log(responseData.data);
};
getItems();
}, []);
澄清一下,如果我刷新浏览器,我只会遇到这个问题。
解决方案
这就是 React 本身。你可以做的是你可以使用如下的 useEffect 钩子,
useEffect(() => {
auth && doSomethingWithAuth(auth);
}, [auth])
但是,理想的解决方案是在读取您的身份验证令牌时显示一些加载组件。您基本上可以将您的提供者提取为另一个组件。然后您可以尝试在您的提供程序组件中读取您的 auth 变量。在开始读取操作时,将状态设置为 authLoading 并在 auth 变为真时将其设置为 false(再次使用 useEffect 挂钩)。最后,如果 authLoading === true,则显示一些加载组件/文本,否则显示提供者的孩子。
希望这可以帮助!
推荐阅读
- c - 从传递的指针打印指向的值
- angular - 如何使用格式化单元格 Angular 导出到 Excel?
- java - 如何更改安装目录选择器附加信息的字体颜色和规格
- libcurl - 问题当 curl_easy_perform 在线程返回代码 7 中运行时
- google-kubernetes-engine - 从私有集群 pod 到另一个私有集群主节点的连接
- javascript - 为来自 webview 的数据调用 vscode 扩展
- php - 如何在触发器文件中访问身份验证响应
- java - 如何在浏览器中显示上传的图片 URL
- xamarin - 如何修复 Xamarin Forms 空白项目构建错误
- java - 滑动刷新布局给出空指针异常