簡體   English   中英

為什么 redux state 渲染不正確?

[英]Why redux state is not render correctly?

美好的一天,當我在用戶正確登錄后嘗試將用戶推送到儀表板時遇到了一個問題,但它沒有,這里是下面的代碼:

登錄表單.js

const { isLoading, isAuth, error, message } = useSelector(
(state) => state.login
);
const handleSubmit = (e) => {
e.preventDefault();
console.log(values);//values={email:'..', pass:'..'}
if (formValidation()) {
  dispatch(NewUserLogin(values)); 
  console.log(isAuth); //print false but in redux state print true
  if (isAuth) history.push('/dashboard');
 }
};

登錄動作.js

export const NewUserLogin = (formValues) => async (dispatch) => {
try {
 dispatch(loginPending());
 const { status, message } = await LoginAPIRequest(formValues);

 if (status === 'success') {
  dispatch(loginSuccess(message));
 } else {
  dispatch(loginFailure(message));
 }
 console.log(status);
 console.log(message);
} catch (error) {
  dispatch(loginFailure(error.message));
 }
};

loginSlice.js

import { createSlice } from '@reduxjs/toolkit';
const initialState = {
isLoading: false,
isAuth: false,
error: '',
};
const loginSlice = createSlice({
 name: 'Login',
 initialState,
 reducers: {
  loginPending: (state) => {
  state.isLoading = true;
  },
  loginSuccess: (state, { payload }) => {
   state.isLoading = false;
   state.isAuth = true;
   state.message = payload;
   state.error = '';
  },
  loginFailure: (state, { payload }) => {
  //actions.payload or shortcut {payload}
   state.isLoading = false;
   state.error = payload;
  },
 },
});

const { reducer, actions } = loginSlice;
export const { loginPending, loginSuccess, loginFailure } = actions;
export default reducer;

用戶API.js

import { createEndpointsAPI, ENDPOINTS } from './index';

export const LoginAPIRequest = (formValues) => {
  return new Promise(async (resolve, reject) => {
  //call api
  try {
    await createEndpointsAPI(ENDPOINTS.LOGIN)
      .create(formValues)
      .then((res) => {
        resolve(res.data);
        if (res.data.status === 'success') {
          resolve(res.data);
          sessionStorage.setItem('accessJWT', res.data.accessJWT);
          localStorage.setItem('sms', JSON.stringify(res.data.refreshJWT));
        }
       console.log(res.data);
      })
     .catch((err) => {
       reject(err);
     });
  } catch (error) {
    console.log(error);
    reject(error);
  }
 });
};

index.js(根 API)

import axios from 'axios';

export const ENDPOINTS = {
  LOGIN: 'user/login',
  LOGOUT: 'user/logout',
  REGISTER: 'user/register',
};

const baseURL = 'http://localhost:3040/v2/';
export const createEndpointsAPI = (endpoint) => {
  let url = baseURL + endpoint + '/';
  return {
   fetchAll: () => axios.get(url),
   fetchById: (id) => axios.get(url + id),
   create: (newData) => axios.post(url, newData),
   update: (updateData, id) => axios.put(url + id, updateData),
   delete: (id) => axios.delete(url + id),
 };
};

isAuth 在登錄正確時返回 false,但在 redux 狀態下顯示 isAuth = true

isAuth 返回 false,然后在第二次單擊登錄后返回 true

isAuth 在 redux 狀態下顯示為 true,而在 console.log(isAuth) 中返回 false

應用程序.js

<MuiThemeProvider theme={theme}>
  <CssBaseline />
  <Router>
    <Switch>
      <Route path='/' exact>
        <Login />
      </Route>
      <PrivateRoute path='/dashboard'>
        <Dashboard />
      </PrivateRoute>
      <Route path='*' component={() => '404 NOT FOUND'} />
    </Switch>
  </Router>
</MuiThemeProvider>

PrivateRoute.js

 import { useSelector } from 'react-redux';

 const PrivateRoute = ({ component: Component, ...rest }) => {
 const { isAuth } = useSelector((state) => state.login);
 console.log(isAuth);
 return (
  <Route
   {...rest}
   render={(props) => {
     isAuth ? (
       <Component {...props} />
     ) : (
       <Redirect
         to={{
           pathname: '/',
           state: { from: props.location },
         }}
       />
      );
      }}
     />
    );
   };

  export default PrivateRoute;

問題是,isAuth 是 redux state,當用戶正確登錄時它應該返回 true,但它不是,我 console.log(isAuth) 第一次打印 false 即使用戶正確登錄,如果我點擊登錄一個更多時間它在控制台日志中打印 true 並將用戶重定向到儀表板頁面。 我不知道為什么isAuth在使用正確登錄時第一次返回false? 請幫助從上到下檢查上述代碼,我為您提供一切。

日志: console.log(isAuth); 記錄一個陳舊的閉包,您可以嘗試對 isAuth 產生影響並在它為真時重定向。

這是一個例子:

const Component = (propps) => {
  const { isLoading, isAuth, error, message } = useSelector(
    (state) => state.login
  );
  const handleSubmit = (e) => {
    //...dispatches but doesn't check isAuth
  };
  useEffect(() => {
    //go to dashboard if isAuth is true
    if (isAuth) history.push('/dashboard');
  }, [isAuth]);//run effect when isAuth changes
};

暫無
暫無

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

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