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

时间:2018-12-25 06:12:25

标签: javascript reactjs redux redux-saga

我在我的项目中使用react,redux和redux-saga。在使用Redux-saga获取用户列表时,我可以看到我的redux存储正在更新(我可以从redux dev工具中看到它),但是在组件中,道具没有改变。

我正在使用一个按钮来获取用户列表。而且用户只出现在该组件中。

App.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

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

    }
}

reducer.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

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)

    ];
}

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

如果您使用Object.assign,并且想要创建状态的新副本,则需要将目标对象更改为新的空对象,而不是当前正在执行的操作(它会使{{1}发生突变}对象,这使得反应无法重新呈现)。 (有关state的更多信息,请参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign。)例如:

Object.assign

尽管如此,我还是建议使用传播运算符代替// copy previous state and new updates to a new empty object return Object.assign({}, state, {userList : action.data});

Object.assign

答案 1 :(得分:0)

如果状态已更新但UI未更新,则表明reducer出了问题。

  • 仔细检查reducer的功能。
  • 如果您在...函数中使用了扩展运算符(reducer),请确保在扩展运算符之后明确提及更新的数据。

减速器的工作示例如下:

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