简体   繁体   English

React 组件未在 redux 状态更新时更新

[英]React component not updating on redux state update

I am using react, redux and redux-saga for my project.我正在为我的项目使用 react、redux 和 redux-saga。 While fetching a list of users using Redux-saga, I can see that my redux store is getting updated (I can see it from the redux dev tool), But in the component , props are not changing.在使用 Redux-saga 获取用户列表时,我可以看到我的 redux 商店正在更新(我可以从 redux 开发工具中看到它),但是在组件中,道具没有改变。

I am using a button to get the list of users.我正在使用一个按钮来获取用户列表。 And the users are showing up in that component only.并且用户仅出现在该组件中。

App.js应用程序.js

import React, { Component } from 'react';
import { connect } from "react-redux";
import './App.css';
import { fetchUsers } from "./actions";
import { Row, Col, ListGroup, ListGroupItem } from "reactstrap";

class App extends Component {

  // eslint-disable-next-line no-useless-constructor
  constructor(props){
    super(props);
  }

  render() {
    console.log("in render func");
    console.log(this.props);
    return (
      <div className="App">
        <h2>Redux Saga App</h2>
        <Row>
          <Col sm={6}>

            {this.props.userList?this.props.userList.map((user)=>(
              user.first_name + user.last_name
            )) : ''}
          </Col>
        </Row>
        <button onClick={this.props.getUserList}>Click to get the users</button>
      </div>
    );
  }
}

const mapStateToProps = (state)=>{
  console.log("in map statetpprop");
  //console.log(state.userList);
  return {userList:state.userList}
}

const mapDispatchToProps = (dispatch)=>{
  return {getUserList :() => {dispatch(fetchUsers())}}
}


App = connect(mapStateToProps,mapDispatchToProps)(App);

export default App;

action.js动作.js

export function fetchUsers(){
    return {
        type:'FETCH_USERS',

    }
}

reducer.js减速器.js

const initialState = {
    userList:[]
}
export function userReducer(state=initialState,action){
    switch(action.type){
        case 'ADD_USER':
            return Object.assign(state,{
                user:action.data
            })
        case 'SET_USERS':
            return Object.assign(state, {userList : action.data});
        default:
            return state;
    }
}

saga.js传奇.js

import {call, put , takeEvery , takeLatest } from 'redux-saga/effects';
import axios from 'axios';
import { setUsers } from "./actions";

export function fetchUsersFunc(userId){

    return axios.get('https://reqres.in/api/users');
}

function* fetchUsers(action){
    const users = yield call(fetchUsersFunc);
    console.log("in fetch users");

    if(users.data.data){
        const userList = users.data.data;
        console.log(userList);
        console.log(userList[0].first_name)
        yield put(setUsers(userList));
    }

}


export function* rootSaga(){
    yield [
        takeLatest('FETCH_USERS',fetchUsers)

    ];
}

Thanks for the help!谢谢您的帮助!

If you use Object.assign and you want to make a new copy of the state, you need to make the target object to a new empty object instead of what you are currently doing (it mutates the state object, which makes the react unable to re-render).如果你使用Object.assign并且你想制作状态的新副本,你需要将目标对象制作成一个新的空对象而不是你当前正在做的事情(它改变了state对象,这使得反应无法重新渲染)。 (You can see See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign for more information on Object.assign ) For example: (有关Object.assign更多信息,请参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign )例如:

// copy previous state and new updates to a new empty object  
return Object.assign({}, state, {userList : action.data}); 

I would recommend using the spread operator instead of Object.assign though:我建议使用扩展运算符而不是Object.assign

return {...state, userList : action.data}

If state is updated but UI is not, it means something went wrong with reducer .如果 state 已更新但 UI 未更新,则意味着reducer

  • Checkout reducer function carefully.仔细检查reducer功能。
  • If you are using spread operator ( ... ) in reducer function, make sure the updated data is mentioned explicitly after spread operator.如果您在reducer函数中使用扩展运算符 ( ... ),请确保在扩展运算符之后明确提及更新的数据。

Example of working reducer function is as below:工作减速器功能示例如下:

const UvNumberReducer = (state=initialState, action: UVAction) => {
  switch(action.type) {
    case UV_NUMBER.LOAD:
      return {
        ...state,
        data: {
          title: action.data.title,
          subtitle: action.data.subtitle
        }
      }
    default:
      return state;
  }
}

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

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