调用分派后组件未更新

时间:2019-02-25 03:03:06

标签: javascript reactjs redux react-redux

我有一个待办事项列表react-redux应用程序,它试图让我了解redux的工作原理。我创建了一个初学者待办事项应用程序。

我遇到的问题是子组件ToDoList.jsx在从另一个文件中调用dispatch时不会更新,但是mapStateToProps 确实存在被调用,并返回正确的信息。该组件只是不重新呈现。

应用说明

有两个组件(app.js除外),AddToList.jsx,具有反映文本字段的标签,和一个按钮,可用于将内容添加到待办事项列表中。

接下来,有一个名为ToDoList.jsx的子组件,它显示要执行的项目的数组。

CodeSandbox

App.js

...
  <div className="App">
    <Provider store={store}>
          <AddToList />
    </Provider>
  </div>
...

AddToList.jsx

...
    <>
        <input type="text" value={props.inputText} placeholder="To do item" onChange={props.inputChangeHandler}/>
        <button type="button" onClick={props.addToListHandler}>Add To List</button>
        <ToDoList />
    </>
...



function mapStateToProps(state) {
    return {
        inputText: state.inputText
    }
}

function mapDispatchToProps(dispatch) {
    return {
        inputChangeHandler: (evt) => {
            const action = {type: 'INPUT_CHANGE', text: evt.target.text};
            dispatch(action);
        },
        addToListHandler: () => {
            const action = {type: 'ADD_TO_LIST'};
            dispatch(action);
        }
    }
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(AddToList);

ToDoList.jsx

import React from 'react';
import { connect } from 'react-redux';

const ToDoList = (props) => {

    return ( 
        <ul>
            {props.toDoList.map((toDoItem, index) => {
                return <li key={index}>{toDoItem}</li>
            })}
        </ul>
     );
}




function mapStateToProps(state) {
    console.log(state.toDoList);
    // ******* Gets Called, and logs correct data **********

    return {
        toDoList: state.toDoList
    };
}


export default connect(
    mapStateToProps
)(ToDoList);

1 个答案:

答案 0 :(得分:1)

问题是您正在使用这段代码:

case "ADD_TO_LIST":
  newState.toDoList.push(state.inputText);
  break;

自从pushnewState.toDoList数组以来,reducer返回相同的对象(但被突变)。当状态更改时,connect将为React组件提供相同的对象。但是,React不会更新列表,因为它是同一对象(通过引用)。

相反,您可以执行以下操作,而不会使原始对象发生变化:

case "ADD_TO_LIST":
  const toDoList = [...state.toDoList, state.inputText];
  newState = {
    ...state,
    toDoList
  };
  break;

在此处查看操作:https://codesandbox.io/s/11764qzpj(但是请注意,仍然存在一个错误!请尝试编辑输入并将其添加到列表中。我将作为练习留给您使用。)


旁注::我还注意到,每次调用reducer时,您都在创建newState。但这是不必要的,而且通常是有害的。如果状态没有变化,则应始终返回原始的state对象。否则,React会认为状态已更改,因此不必要地尝试重新渲染组件。