javascript - 如何在反应中将句柄更改添加到待办事项应用程序?
问题描述
我是新来的反应和制作待办事项应用程序。
我添加了一个事件侦听器(handleChange)来将 todosData.completed 从 true 翻转为 false,反之亦然,从而允许用户选中和取消选中复选框。
我该如何纠正这一点。这是我的代码:
class App extends React.Component {
constructor() {
super();
this.state = {
todos: todosData
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(id) {
this.setState(prevState => {
const updatedTodos = prevState.todos.map(todo => {
if (todo.id === id) {
todo.completed = !todo.completed;
}
return todo;
});
return {
todos : updatedTodos
};
});
}
render() {
const todoItems = this.state.todos.map(item => (
<TodoItem
key={item.id}
item={item}
handleChange={this.handleChange}/>
));
return(
<div>{todoItems}</div>
);
}
}
export default App;
function TodoItem(props) {
return (
<div>
<input
type = 'checkbox' checked = {props.item.completed}
onChange = {() => props.handleChange(props.item.id)} />
<p> {props.item.task} </p>
</div>
);
}
export default TodoItem;
有人能告诉我我错过了什么吗?
解决方案
正如@ChrisG 在评论中指出的那样,当您的组件被包裹在<React.StrictMode>
. 如果您使用 Create React App 创建了您的应用程序,默认情况下会这样做,请检查您的index.js
文件。
StrictMode 是一项开发功能,可迫使您编写更好的代码。它只影响您的开发构建,因此如果在生产模式下构建和运行,您的代码应该可以工作。
StrictMode 所做的一件事就是运行你的setState
方法两次,以确保你不依赖它只运行一次。因此,第一次运行时,您按预期反转 todo.completed,第二次将其恢复为原始值。
这告诉您的是,您的handleChange
函数实际上是在使用非纯方法更新状态,因为您实际上更改todo
了prevState.todos.map
.
相反,您需要做的是返回一个新todo
对象,该对象将是另一个对象的副本,仅completed
修改了属性,如下所示:
handleChange(id) {
this.setState(prevState => {
const updatedTodos = prevState.todos.map(todo => {
return {
id: todo.id,
task: todo.task,
completed: todo.id === id ? !todo.completed : todo.completed
};
});
return {
todos: updatedTodos
};
});
}
或者使用ES6 扩展运算符,如下所示:
handleChange(id) {
this.setState(prevState => (
{
todos: prevState.todos.map(todo => (
{...todo, completed: todo.id === id ? !todo.completed : todo.completed}
))
}
));
}
我相信这是一个比 Chris G 建议删除 <React.StrictMode> 更好的解决方案,因为 StrictMode 实际上可以帮助您编写更好的代码。
推荐阅读
- angular - 反应形式中的形式
- regex - 使用带有环境变量的 sed 替换文件中的文本
- mongodb - 我可以在 mongodb 的 $push 中使用现有的文档字段值吗?我尝试了以下方法,它不起作用
- java - 用逗号分割字符串,但不包括任何数字的双引号,而只包括字符串
- shell - 如何将 Jenkins 构建中的“params”对象回显到 shell 中的 sed 指令中?
- javascript - highcharts $_post['value'] 不打印图表值
- typescript - 直接返回值 vs 返回期望值的变量
- graphql - 在嵌套对象上具有冲突约束的 Upsert Graphql Mutation
- angular - 没有表单的角度模式验证
- nginx - Meteor Up 负载均衡器