【问题标题】:React cannot use the updated Redux state after having dispatched an actionReact 在 dispatch 一个 action 后不能使用更新后的 Redux 状态
【发布时间】:2021-03-01 03:27:09
【问题描述】:

我对 React 和 Redux 比较陌生,通过我的个人项目学习它们。

这里的问题是isAuthedrest.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
        }

【问题讨论】:

    标签: javascript reactjs redux redux-thunk


    【解决方案1】:

    您不希望像verifyUser(); 这样的函数调用只是浮动在组件中。它需要在 useEffect 挂钩内。

    您的Login 组件会在您重定向到Dashboard 之前获取端点,因此您无需再次获取端点 即可通过PrivateRoute 访问Dashboard

    您可以将initialState 更改为包含isAuthenticated: undefined,如“我们不知道他们是否通过身份验证,因为我们尚未检查。”

    那么在PrivateRoute中,如果isAuthed的值是undefined,我们只需要调用verifyUser,也就是说我们还没有检查。如果是 truefalse,我们只使用现有的值。

    aysnc 流程仍然存在一些问题,因为我们不想在verifyUser 完成之前将Redirect 关闭PrivateRoute。为此,我们可以有条件地呈现在等待凭据时显示的加载状态。

    我不知道这是最优雅的解决方案,但它应该可以工作

    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 } }}
              />
            )
          }
        />
      );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-01
      • 2019-08-18
      • 2019-12-29
      • 2019-08-24
      • 1970-01-01
      • 2017-03-22
      • 2020-03-30
      相关资源
      最近更新 更多