reactjs - 从没有 setState 的输入更新对象
问题描述
我是 React JS(和 JS,一般来说)的新手。现在我正在尝试编写一个简单的任务跟踪器。
所以,我在MyTodoList类的状态元素中有所有任务。在那里,我使用Task常量分别绘制每个任务。
我想用 2 个输入实现添加一个新任务:名称和描述。
我在MyTodoList中创建一个新对象(newTask),以便稍后将其添加到状态列表中。但是,我想我正在为输入错误编写 onChange 方法。newTask 似乎正在函数内部更新(将其记录在控制台中),但它在外部没有改变(在输入空间中,输入没有变化)。显然我不能使用 setState 因为我想更新一个非状态对象(对象是可变的,所以我不明白为什么它不会改变)。
我不确定我是否错误地更新了对象,或者我添加新任务的整个概念是否错误。如果您能解释我的错误,将不胜感激。
这是代码:
const TaskAdd = ({value, onChange, placeholder, name}) => {
return (
<input value={value} onChange={onChange} placeholder={placeholder} name={name}/>
)
}
const Task = ({id, name, description, completed}) => {
const handleClick = () => {
}
return (
<div className='task'>
<h3>{name}</h3>
<div>{description}</div>
<div>{completed}</div>
<button onClick={handleClick} className='button1'>CLICK</button>
</div>
)
}
class MyTodoList extends React.Component {
state = {
tasks: [
{
id: 1,
name: 'Walk the dog',
description: 'Have to walk the dog today',
completed: false,
},
]
}
maxId = this.state.tasks[this.state.tasks.length - 1].id;
newTask = {
id: this.maxId,
name: '',
description: '',
completed: false,
}
handleChange = (event) => {
const {value, name} = event.currentTarget
this.newTask[name] = this.newTask[name] + value
}
render () {
return(
<div>
<header><h1>TO-DO</h1></header>
<div className='addTask'>
<h2>Let's add something new</h2>
<TaskAdd value={this.newTask.name} onChange={this.handleChange}
placeholder='Name' name='name'/>
<TaskAdd value={this.newTask.description} onChange={this.handleChange}
placeholder='Description' name='description'/>
<p> {this.newTask.name}</p>
<button className='button1'><h3>Add</h3></button>
</div>
<div>{this.state.tasks.map(task => <Task id={task.id} name={task.name}
description={task.description} completed={task.completed}/>)}
</div>
</div>
)
}
}
const App = () => {
return (
<MyTodoList />
)
}
export default App;
解决方案
显然我不能使用 setState 因为我想更新一个非状态对象
如果要更新屏幕,则必须使用 state。setState 函数是告诉 react 某些东西发生了变化并且需要重新渲染的唯一方法。
因此,扩展您的状态以在其中包含新任务:
state = {
tasks: [
{
id: 1,
name: 'Walk the dog',
description: 'Have to walk the dog today',
completed: false,
},
]
newTask: {
id: 2,
name: '',
description: '',
completed: false,
}
}
有了它,您需要更新您的渲染函数以在状态下访问它,如下所示:
<TaskAdd
value={this.state.newTask.name}
onChange={this.handleChange}
placeholder='Name'
name='name'
/>
然后当你设置状态时,制作一个副本而不是变异:
handleChange = (event) => {
const {value, name} = event.currentTarget
this.setState({
newTask: {
...this.state.newTask,
[name]: this.state.newTask[name] + value
}
});
}
您的代码没有包含 add 按钮的实现,但是当您这样做时,您可能会使用 this.state.newTask 并将其添加到 this.state.tasks 的末尾(您将制作数组的副本,而不是改变它),然后创建一个新对象来替换 this.state.newTask
*好的,从技术上讲,有 forceUpdate,但不要使用它。
推荐阅读
- laravel - 虚拟主机在 Mac OS 上收到禁止错误消息
- intellij-idea - 如何获得新的 Codename One GUI 构建器?我在任何地方都找不到下载链接
- php - 为什么使用 move_uploaded_file 函数后图像文件损坏
- mysql - 恢复 mysqldump 文件时出现 mysql ERROR 1064 (42000)
- using - 在 NEOS 服务器中使用 Pyomo 调用求解器后如何访问日志文件的内容?
- android - 在 Android 手机上未调用 onkeypress 的 Angular 指令
- python - 如何使用 python 和烧瓶刷新 api 值
- python - 如何使用参数?
- reactjs - Visual Studio 代码中的 React.Fragment 错误
- javascript - 鼠标悬停事件不适用于覆盖的对象