簡體   English   中英

在調度一個動作后,React 不能使用更新的 Redux state

[英]React cannot use the updated Redux state after having dispatched an action

我對 React 和 Redux 比較陌生,並通過我的個人項目學習它們。

這里的問題是執行rest.dispatch(actions.isValidUser(json)) isAuthed使用更新的 Redux state。 據我所知,Redux state 是由動作更新的。 (但我沒有看到在更新后調用了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
        }

您不想要像verifyUser(); 只是漂浮在組件中。 它需要在useEffect掛鈎內。

您的Login組件會在您重定向到Dashboard之前獲取端點,因此您無需再次獲取端點即可通過PrivateRoute訪問Dashboard

您可以更改您的initialState以包括isAuthenticated: undefined ,如“我們不知道它們是否經過身份驗證,因為我們尚未檢查。”

然后在PrivateRoute中,如果isAuthed的值是undefined意味着我們還沒有檢查,我們只需要調用verifyUser 如果它是truefalse ,我們只使用現有的值。

我們的 aysnc 流程仍然存在一些問題,因為我們不想在verifyUser完成之前RedirectPrivateRoute 為此,我們可以有條件地呈現在等待憑據時顯示的加載 state。

我不知道這是最優雅的解決方案,但它應該可以工作

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM