我使用 react-redux 管理状态,使用 axios 进行 API 调用。
我的默认状态:
const defaultState = {
isLoading: true,
isAuthenticated: false,
authUser: {}
}
一旦 API 的登录调用成功运行,isLoading
和 authUser
都会更新。这里没有错。
在 userProfile 组件中,我使用以下内容从商店获取登录用户的 ID:
const authUser = useSelector(state => state.authentication.authUser);
const user = users.getUser(authUser.id);
console.log(authUser);
authUser
在页面加载时始终为空,但会延迟一秒钟,它再次打印,这次是状态内容。
我在自定义 PrivateRoute
组件后面有 userProfile 组件:
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 个控制台日志一个接一个出现。第一个是空的,第二个是数据。
我在这里错过了什么?这种异步的东西让我发疯!
答案 0 :(得分:0)
通过私有路由的这种实现,你可以保存用户的当前路径,让用户再次登录后继续他的过程
import React from 'react';
import { Login } from '../../pageComponents';
import { useSelector } from 'react-redux';
const PrivateRoute = (Component) => {
const Auth = (props) => {
const { isLoggedIn } = useSelector((state) => state.user);
// Login data added to props via redux-store (or use react context for example)
// If user is not logged in, return login componentc
if (!isLoggedIn) {
return <Login />;
}
// If user is logged in, return original component
return <Component {...props} />;
};
// Copy getInitial props so it will run as well
if (Component.getInitialProps) {
Auth.getInitialProps = Component.getInitialProps;
}
return Auth;
};
export default PrivateRoute;
然后在每个你想要 Private Rout 的页面使用它,如下所示
const myPrivateRoute = () => {
return (
<h1>Hello world</h1>
)
}
export default PrivateRoute(myPrivateRoute)
答案 1 :(得分:0)
所以创建这样的组件并从本地存储或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 文件中
app.js
render() {
return (
<React.Fragment>
<Provider store={store}>
<ErrorBoundary>
<StorageManagment />
<DefaultLayout>
<Application {...this.props} />
</DefaultLayout>
</ErrorBoundary>
</Provider>
</React.Fragment>
);
}