reactjs - 在组件中使用 useSelector() 的结果
问题描述
我正在使用 react-redux 来管理状态和 axios 来进行 API 调用。
我的默认状态:
const defaultState = {
isLoading: true,
isAuthenticated: false,
authUser: {}
}
isLoading
authUser
一旦 API 的登录调用成功运行,两者都会更新。这里没有错。
在 userProfile 组件中,我使用以下内容从商店获取登录用户的 ID:
const authUser = useSelector(state => state.authentication.authUser);
const user = users.getUser(authUser.id);
console.log(authUser);
authUser
页面加载时总是空的,但迟了一秒,它再次打印,这次是状态内容。
我在自定义组件后面有 userProfilePrivateRoute
组件:
const PrivateRoute = ({ component: Component, ...rest }) => {
const authentication = useSelector(state => state.authentication);
return (
<Route
{...rest}
render={props =>
authentication.isAuthenticated ? (
<Component {...props} />
) : (
authentication.isLoading ? 'loading...' :
<Redirect to={{ pathname: '/login', state: { from: props.location } }} />
)
}
/>
)
};
loading...
文本在组件赶上之前显示,然后 2 个控制台日志一个接一个地出现。第一个是空的,第二个是数据。
我在这里想念什么?这种异步的东西快把我逼疯了!
解决方案
所以像这样创建组件并从本地存储或cookie加载你的最后一部分然后验证并发送到你的redux存储然后你可以记住日志
import { useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import axios from "axios";
import * as globalActions from "../../../store/actions/globalAction";
import * as userAction from "../../../store/actions/userAction";
const StorageManagment = () => {
const dispatch = useDispatch();
/* ----------------------------------- listening to token changes ----------------------------------- */
useEffect(() => {
dispatch(userAction.loadCart());
}, []);
useEffect(async () => {
try {
if (window)
await checkLocalDataWithRedux()
.then((data) => {
const { userDTO, token } = data;
dispatch(userAction.loginUser(token, userDTO));
})
.catch((e) => {
console.log(e);
dispatch(userAction.logOutUser());
});
} catch (e) {
throw e;
}
}, []);
function checkLocalDataWithRedux() {
return new Promise((resolve, reject) => {
try {
/* -------- read user data from localStorage and set into redux store ------- */
const { userDTO, token } = localStorage;
if (userDTO && token) {
resolve({ token: token, userDTO: JSON.parse(userDTO) });
} else logOutUser();
} catch (e) {
reject();
}
});
}
function logOutUser() {
dispatch(userAction.logOutUser());
}
return null;
};
export default StorageManagment;
然后将其加载到您的 app.jsx 文件中
应用程序.js
render() {
return (
<React.Fragment>
<Provider store={store}>
<ErrorBoundary>
<StorageManagment />
<DefaultLayout>
<Application {...this.props} />
</DefaultLayout>
</ErrorBoundary>
</Provider>
</React.Fragment>
);
}
推荐阅读
- javascript - 典型的 HTTP 会话,但 Ajax 风格
- c# - Xamarin 形式。如何绑定选择器的选定项目以在切换视图时显示在选择器字段中?
- javascript - JavaScript fetch() - 将 ReadableStreams 数组映射到数组
- netlogo - Netlogo:通过滑块输入概率
- big-o - 试图理解这个 big0 符号的复杂性
- python - 生成与任意维度上的一组其他向量正交的向量
- c++ - 如何通过指定的行和列获取 Clang AST 节点?
- python - Reportlab,如何更改页面方向?
- python - 在张量流中逐元素地从两个张量中获取更高的值
- r - 使用 styler 设置 R 代码样式时,使用 = 而不是 <- 进行赋值