繁体   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