我有一个待办事项列表react-redux应用程序,它试图让我了解redux的工作原理。我创建了一个初学者待办事项应用程序。
我遇到的问题是子组件ToDoList.jsx
在从另一个文件中调用dispatch
时不会更新,但是mapStateToProps
确实存在被调用,并返回正确的信息。该组件只是不重新呈现。
有两个组件(app.js除外),AddToList.jsx
,具有反映文本字段的标签,和一个按钮,可用于将内容添加到待办事项列表中。
接下来,有一个名为ToDoList.jsx
的子组件,它显示要执行的项目的数组。
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);
答案 0 :(得分:1)
问题是您正在使用这段代码:
case "ADD_TO_LIST":
newState.toDoList.push(state.inputText);
break;
自从push
到newState.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会认为状态已更改,因此不必要地尝试重新渲染组件。