繁体   English   中英

React/Redux 不更新 state

[英]React/Redux not updating the state

我刚从 redux 开始,我想将它包含在我现有的应用程序中。 我想要做的是store我的登录响应,以便我在其他页面上使用用户详细信息。

登陆页面.js

import { useDispatch } from 'react-redux'

function LandingPage(){
  const dispatch = useDispatch();
  const authLogin = async()=>{
  const response = await axios.get('/api',)
  let responseValue = response.data.success
  if(responseValue === true) {
     const parsedData = JSON.parse(response.data.resp)
     dispatch({
       type: 'SAVE_AUTH',
       payload: {
         isLoggedIn: responseValue,
         username: parsedData.data.user.userName,
         token: parsedData.data.token
       }
     })
  }
useEffect(() => {
authLogin();
  }, [])
return (
<div>
  <label>Authenticating....</label>
  <Login1 /> //updated based on @LindaPaiste's answer
</div>
export default LandingPage;

MainLanding.js

import React from 'react'
import Login1 from './Login1'
function MainLanding(){
return(
    <div>
        <h1>User Login Details</h1>
        <Login1 /> //Nothing hapens here
    </div>
)
}
export default MainLanding;

登录1.js

import React from 'react'
import LoginDetailsx from './LoginDetailsx'
import { useSelector } from 'react-redux'
function Login1(){
const userLoginDetails = useSelector((state) => state.loginDetails)
console.log('userLoginDetails',userLoginDetails)
return(
    <div>
        <h2>Login Details</h2>
        <LoginDetailsx isLogin={userLoginDetails.isLoggedIn} username={userLoginDetails.username} token={userLoginDetails.token}/>
        })}
        
    </div>
)}
export default Login1;

loginDetailsReducer.js

const initialState = [
{
    isLoggedIn: false,
    
}];

const loginDetailsReducer = (state = initialState, action) => {
const { type, payload } = action;
console.log('typex',type)
console.log('payloadx',payload)

switch(type){
    case "SAVE_AUTH":
        alert('dasdasd')
        return payload;
    case "LOGOUT_AUTH":
        return initialState
    default:
        return state;
}
}
export default loginDetailsReducer;

rootReducer.js

import { combineReducers } from 'redux'
import loginDetailsReducer from '../reduxReducers/loginDetailsReducer'
const rootReducer = combineReducers({
  loginDetails: loginDetailsReducer
});
export default rootReducer;

store.js

import { createStore } from 'redux'
import rootReducer from '../reduxReducers/rootReducer'
const store = createStore(rootReducer);
export default store;

LoginDetailsx.js

import React from 'react'
function LoginDetailsx(props){
return(
    <div>
        <p>Details: isloggedin: {props.isloggedin}, username: {props.username}, token: {props.token}</p>
    </div>
   )
}
export default LoginDetailsx;

这就是我在成功登录后在MainLanding.js上得到的。 在此处输入图像描述

这就是我在LandingPage.js console.log上得到的在此处输入图像描述

State 形状

虽然不一定是问题,但loginDetails state 应该是一个array确实没有意义。 一次只能登录一个用户,因此它应该只是带有用户详细信息的 object。 这使您的减速器非常简单(一如既往的 Redux 工具包可以使其更加简单)。

您还需要添加一个注销案例。 isLoggedIn应该是boolean而不是string 我个人认为,当没有登录用户时,对于usernametokenundefined''更有意义,但这取决于你。

const initialState = {
    isLoggedIn: false,
    // no username or token when logged out
};

const loginDetailsReducer = (state = initialState, action) => {
    const { type, payload } = action;
    switch(type) {
        case "SAVE_AUTH":
            // replace the state with the action payload
            return payload;
        case "LOGOUT_AUTH":
            // revert to initial state
            return initialState;
        default:
            return state;
    }
}

export default loginDetailsReducer;

在登录

我要说的是,像 API 调用这样的异步操作需要在组件的useEffect挂钩内完成。 您可以在安装组件时使用一个空的依赖数组来运行一次效果。

useEffect(() => {
    authLogin();
}, []);

但是现在我正在查看您的图像,您似乎正在执行操作以响应按钮单击,所以这也很好。

axios handles JSON parsing so you should not need to use JSON.parse() (unless your API is returning strange data).

function MainLanding() {
  const isLoggedIn = useSelector((state) => state.loginDetails.isLoggedIn);

  // access dispatch function
  const dispatch = useDispatch();

  // define the function to log in
  const authLogin = async () => {
    const response = await axios.get("/api");
    const data = response.data;
    if (data.success === true) {
      dispatch({
        type: "SAVE_AUTH",
        payload: {
          isLoggedIn: true,
          username: data.resp.user.userName,
          token: data.resp.data.token
        }
      });
    }
  };

  return (
    <div>
      {isLoggedIn ? (
        <>
          <h1>User Login Details</h1>
          <Login1 />
        </>
      ) : (
        <button onClick={authLogin}>Log In</button>
      )}
    </div>
  );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM