reactjs - REACT - useContext 状态共享同步问题
问题描述
客观的 : -
我希望用户只有在登录时才能看到他/她的订单。所以我使用 AuthContext 对登录数据+令牌的用户进行状态管理。
问题 : -
当我将令牌从 AuthContext 传递给子组件时,AuthContext 需要一些时间来使用后端验证令牌,同时子组件的逻辑会中断。
子组件(使用状态/令牌):
const MyOrders = () => {
const { userData } = useContext(AuthContext);
const history = useHistory();
if (!userData.token) { // This redirects the user back to the home page immediately
history.push("/"); // because the token hasn't been passed yet when
// the component is loaded
};
const getOrders = async () => {
const url = 'http://localhost:5000/api/orders';
try {
const res = await axios.get(url, {
headers: {
'x-auth-token': userData.token
}
});
console.log(res.data);
} catch (err) {
console.log(err.response);
}
};
useEffect(() => {
if (userData.token) getOrders();
}, []);
解决方法(安全吗????)
const MyOrders = () => {
const token = localStorage.getItem('auth-token'); // Use localStorage token directly instead of
// validating the token first (from AuthContext)??
const history = useHistory();
if (!token) {
history.push("/");
};
const getOrders = async () => {
const url = 'http://localhost:5000/api/orders';
try {
const res = await axios.get(url, {
headers: {
'x-auth-token': token
}
});
console.log(res.data);
} catch (err) {
console.log(err.response);
}
};
useEffect(() => {
if (userData.token) getOrders();
}, []);
Parent Component (AuthContext) : // 如果有人需要
const AuthContextProvider = (props) => {
const [userData, setUserData] = useState({
token: undefined,
user: undefined
});
//Need to check if user is logged in
//every time the App is rendered
useEffect(() => {
const checkLoggedIn = async () => {
const url = "http://localhost:5000/api/users/token";
let token = localStorage.getItem("auth-token");
//when user is not logged in
if(token === null) {
localStorage.setItem("auth-token", "");
token = "";
}
//need to validate the token if it exists
const tokenResponse = await axios.post(url, null, {
headers: { "x-auth-token": token }
});
//if token is valid, collect user data
if(tokenResponse.data){
console.log(tokenResponse);
setUserData({
token,
user: tokenResponse.data,
});
} else {
localStorage.setItem("auth-token", "");
token = "";
};
};
checkLoggedIn();
}, []);
解决方案
我建议您尝试在应用程序的第一页中检索保存的令牌。在函数上使用“等待”。尝试从 localStorage 检索完成后,如果令牌不存在,您应该导航到登录,否则导航到主页。在这种情况下,如果您有令牌,您将不会有未定义的令牌,
但是如果令牌以某种方式未定义怎么办?如果用户尝试使用未定义的令牌获取,则需要从服务器发送未经授权的错误,然后在客户端捕获错误,检查您收到的消息和类型,如果出现授权错误,导航到主页页。
这是一个有点复杂的答案,但它肯定会解决你的问题,它会让它更干净的代码和可靠的。
推荐阅读
- powershell - 在每个自己的 Out-GridView 中显示每个 AD 组的 AD 组成员
- javascript - 检查javascript对象是否有密钥,如果它确实用新密钥替换它
- javascript - React类组件中的Javascript“无法读取未定义的属性”
- c# - 使用 Visual Studio 2019 C# 将静态方法重构为扩展方法
- javascript - 如何防止网站加载到网页的特定部分
- python - 如何从字符串中选择特定的字符串?
- android - Android TextView分离内部布局问题
- python - Django 状态字段
- asp.net - ASP.NET - 当文件名包含斜杠/时下载文件
- python - Python:如何将 API 请求中的文本/CSV 内容异步发送到 Google Cloud Storage?