【发布时间】:2020-06-01 19:00:13
【问题描述】:
我用于身份验证的上下文存在问题。如果我在登录时 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();
}, []);
为了澄清,我只有在刷新浏览器时才会遇到这个问题。
【问题讨论】:
-
我没有看到你在哪里使用
auth和useContext(AuthContext)或者你在组件树中的哪里有AuthContext.Provider。如果你没有这两件事的代码,那肯定会导致你的问题;如果您有代码,请将其发布为尽可能简化的表格。 -
React 重新渲染更改。您将 loggedIn 设置为
false以进行初始渲染。登录将重新呈现所需的上下文和子组件。这就是 react 的工作原理,并不意味着它很慢。 -
@JoshWilson,添加了我的 App.js 的快速示例供您查看
-
@Andre,问题是当我尝试在受保护的管理区域中发出获取请求时,它最初会失败,因为我必须在标头中发送令牌,但因为令牌在第一次加载时不存在, 它失败。这是我的问题,第一个 console.log 为假,然后一秒钟后我在控制台中看到了令牌。我想在第一个 console.log 上看到它,不希望它加载两次
标签: reactjs react-hooks react-context