我对 React 和 Redux 比较陌生,并通过我的个人项目学习它们。
这里的问题是 isAuthed
在执行 rest.dispatch(actions.isValidUser(json))
后无法使用更新的 Redux 状态。据我所知,Redux 状态是由操作更新的。 (但我没有看到更新后调用了 connect()
...我不知道这是否与此问题有关。)
我还尝试在我的操作文件中使用 Redux-thunk 从 API 端点获取数据并使用 useEffect(),但它没有解决问题。你能帮我吗?
提前致谢。
**ProtedtedRoute.jsx**
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import * as actions from '../actions/actions';
function ProtectedRoute({ component: Component, isAuthed, ...rest }) {
async function verifyUser() {
// checking if a user is valid by checking JWT
const res = await fetch(ENDPOINT, reqOptions);
if (res.status === 200) {
const json = await res.json();
rest.dispatch(actions.isValidUser(json));
} else {
// failure handling
};
};
verifyUser();
return (
<Route
{...rest}
render={(props) => isAuthed == true ? <Component {...props} /> : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />}
/>
);
};
export default connect(state => {
return {
isAuthed: state.isAuthenticated
}
})(ProtectedRoute);
**reducer.js**
const initState = {
data: {},
// when a user is valid, it will be ```true```
isAuthenticated: false
}
**App.js**
function App() {
return (
<Provider store={store}>
<BrowserRouter>
<div>
<div className="content">
<Switch>
<Route exact path="/" component={Home} />
<PublicRoute path="/login" component={LogIn} />
<PublicRoute path="/signup" component={SignUp} />
<ProtectedRoute path="/dashboard" component={Dashboard} />
</Switch>
...
**Login.jsx**
const res = await fetch(ENDPOINT, { reqOptions});
if (res.status === 200) {
props.history.push('/dashboard');
else{
// error handling
}
答案 0 :(得分:0)
您不希望像 verifyUser();
这样的函数调用只是漂浮在组件中。它需要位于 useEffect
钩子内。
您的 Login
组件会在您重定向到 Dashboard
之前获取端点,因此您无需再次获取端点即可访问 Dashboard
通过PrivateRoute
。
您可以更改您的 initialState
以包含 isAuthenticated: undefined
,如“我们不知道它们是否通过身份验证,因为我们还没有检查过。”
那么在PrivateRoute
中,我们只需要在verifyUser
的值为isAuthed
时调用undefined
,这意味着我们还没有检查。如果是 true
或 false
,我们只使用现有值。
我们的 aysnc 流程仍然存在一些问题,因为我们不想在 Redirect
完成之前 PrivateRoute
离开 verifyUser
。为此,我们可以有条件地呈现在等待凭据时显示的加载状态。
我不知道这是最优雅的解决方案,但它应该有效
function ProtectedRoute({ component: Component, isAuthed, ...rest }) {
async function verifyUser() {
// checking if a user is valid by checking JWT
const res = await fetch(ENDPOINT, reqOptions);
if (res.status === 200) {
const json = await res.json();
rest.dispatch(actions.isValidUser(json));
} else {
// failure handling
}
}
useEffect(() => {
if (isAuthed === undefined) {
verifyUser();
}
}, [isAuthed]); //re-run when isAuthed changes
return (
<Route
{...rest}
render={(props) =>
isAuthed === undefined ? (
<Loading />
) : isAuthed === true ? (
<Component {...props} />
) : (
<Redirect
to={{ pathname: "/login", state: { from: props.location } }}
/>
)
}
/>
);
}