我正在尝试使用react-redux
构建一个简单的 todo-app 。问题是当我尝试更新数据时,它不会在视图中更新。我的代码如下:
动作
export const listTodo = () => { type: actionTypes.LIST_TODO }
export const updateTodo = ( payload, index ) => { type: actionTypes.UPDATE_TODO, payload, index }
减速器
const INITIAL_STATE = {
all: [{
name: 'init',
status: false,
lastUpdate: new Date().toISOString()
}]
}
const listTodo = ( state, action ) => {...state, all: state.all }
const updateTodo = ( state, action ) => {
const listTodo = {...state, all: state.all }; // init data
// find data
let todo = listTodo.all.filter( (todo, index) => index === action.index );
// update data
todo.name = action.payload.name;
todo.status = action.payload.status;
todo.lastUpdate = new Date().toISOString();
listTodo.all[ action.index ] = todo;
// return data
return {
...state,
all: listTodo.all
}
}
export default ( state = INITIAL_STATE, action) => {
switch( action.type ) {
case LIST_TODO:
return listTodo( state, action );
case UPDATE_TODO:
return updateTodo( state, action );
default:
return state;
}
}
在下面的代码(Components/list.js
中,我只是获取所有待办事项列表,然后使用ShowList
打印所有列表。
Components / list.js
import ShowList from '../container/showList';
class TodoList extends Component {
renderTodoList() {
return this.props.all.map( (todo, index) => {
return (
<ShowList key={index} index={index} todo={todo} />
);
});
}
render() {
return <ul> { this.renderTodoList() } </ul>
}
}
const mapStateToProps = ( state ) => { all: state.todo.all };
export default connect( mapStateToProps ) ( TodoList );
在下面的代码(container/showList.js
)中,待办事项列表使用<li />
显示,并且还有一个checkbox
,当用户单击复选框时,handleCheckbox
将触发并会更新待办事项清单。我相信数据已正确更新,但并未在html
上更新。在浏览器中,待办事项列表与以前相同。
容器/showList.js
class ShowList extends Component {
handleCheckbox = ( ) => {
const { todo, index } = this.props;
todo.status = !todo.status;
todo.lastUpdate = new Date().toISOString();
this.props.onUpdateTodo( todo, index );
}
render() {
const { todo, index } = this.props;
return (
<li> <input type="checkbox" onChange={ this.handleCheckbox } checked={todo.status} /> {todo.name} # {todo.status.toString()} # { todo.lastUpdate } </li>
)
}
}
const mapDispatchToProps = ( dispatch ) => onUpdateTodo: ( todo, index ) => dispatch( actions.updateTodo( todo, index ) )
export default connect(null, mapDispatchToProps) (ShowList);
如何解决此问题?预先感谢。
答案 0 :(得分:1)
您的问题在这一行,
export const updateTodo = ( payload, index ) => { type: actionTypes.UPDATE_TODO, payload, index }
Redux Action
仅使用2
个参数,分别为type
和payload
。
您在这里传递了3
参数,这是错误的。删除您的index
参数,您的操作将变成这样,
export const updateTodo = ( payload, index ) => { type: actionTypes.UPDATE_TODO, payload } //payload = your updated todo list
仅将更新的待办事项列表传递给您的操作,
this.props.onUpdateTodo( todo );
最后,仅在您的reducer
中这样做
return Object.assign(state,action.todo) // This will merge your old state with updated todo list and eventually you will get a updated list.
查看更多Object.assign
here
答案 1 :(得分:1)
您的问题出在您的reducers文件中。每当执行updateToDo()
时,您实际上并没有在更新现有的待办事项,而只是将新属性添加到具有新更改的状态中。这将创建图层和属性图层,而无需实际更新第一层。而且,由于您的组件仅连接到第一层,因此它将永远无法获得更新状态。
我已经更新了一个代码框供您参考:https://codesandbox.io/s/lively-flower-mwh79
您可以将reducer更新为类似的代码,然后代码可以正常工作:
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case "LIST_TODO":
return listTodo(state, action);
case "UPDATE_TODO":
return {
...state,
all: state.all.map((todo, index) => {
if (index == action.index) {
return {
...todo,
status: todo.status,
lastUpdate: new Date().toISOString()
};
} else {
return todo;
}
})
};
default:
return state;
}
};