我正在使用以下JSX代码在React应用程序的一部分上创建待办事项:
<form>
<div>
<label htmlFor="subject">Subject: </label>
<input type="text" value={todo.subject} onChange={e => handleInput(e, 'subject')} name="subject" id="subject"></input>
</div>
<div>
<label htmlFor="duedate">Due date: </label>
<input type="date" value={todo.duedate} onChange={e => handleInput(e, 'duedate')} name="duedate" id="duedate"></input>
</div>
<div>
<label htmlFor="description">Description: </label>
<textarea value={todo.description} onChange={e => handleInput(e, 'description')} name="description" id="description"></textarea>
</div>
<div>
<label htmlFor="sidenote">Sidenotes: </label>
<textarea value={todo.sidenote} onChange={e => handleInput(e, 'sidenote')} name="sidenote" id="sidenote"></textarea>
</div>
<button type="submit" onClick={e => handleSubmit(e)}>Submit</button>
</form>
todo
状态和handleInput
的定义如下:
const [todo, setTodo] = useState({
'subject': '',
'duedate': '',
'description': '',
'sidenote': ''
});
const handleInput = (e, field) => {
e.persist();
setTodo(prevTodo => {
prevTodo[field] = e.target.value;
return prevTodo;
});
}
在输入更改后运行console.log(todo)
,可以确认状态是否正确更新;但是,这些状态更改不会呈现为输入元素的value
。相反,将handleInput
更改为以下内容可以解决问题:
const handleInput = (e, field) => {
e.persist();
setTodo(prevTodo => {
let newTodo = {...prevTodo};
newTodo[field] = e.target.value;
return newTodo;
});
}
考虑到两个功能均正确更新了todo
状态,是什么原因导致后一个功能正常工作,而前一个却无效?
答案 0 :(得分:1)
通常,在您的情况下,您必须返回一个浅表复制对象,而不仅仅是修改当前参考状态的键,因为React不会比较键的深处,它只是通过Tabs tabs = new Tabs();
tabs.setOrientation(Tabs.Orientation.VERTICAL);
进行比较以检查当前状态和下一个状态不同,然后决定是否重新渲染,也可以重新编写以使其正常工作:
===