我创建了以下演示来帮助我描述我的问题:https://codesandbox.io/s/dazzling-https-6ztj2
我有一个表单,可以在其中提交信息并将其存储在数据库中。在另一页上,我检索此数据,并相应地为复选框设置checked
属性。这部分有效,在演示中,它由dataFromAPI
变量表示。
现在,问题是当我想更新复选框时,出现各种错误,而且我不知道如何解决。最终目的是我修改表单(取消选中此复选框,反之亦然),然后将其发送给数据库-本质上这是一个UPDATE操作,但同样在演示中不可见。
有什么建议吗?
还要注意,我已经简化了演示,在我正在开发的真实应用中,我在state
中有多个表单元素和多个值。
答案 0 :(得分:1)
我建议您使用所有id或希望用作列表键的数组,并在数组https://reactjs.org/docs/lists-and-keys.html上使用“映射”。 它还可以帮助您将每个复选框元素作为一个项目进行控制。
答案 1 :(得分:0)
添加或删除都无法按原样工作。
Array.push
返回新数组的 length ,而不是新数组。
Array.splice
返回由已删除项组成的新数组。并且它会更改您不应该使用的原始文件。我们将改用filter
。
将状态设置器更改为此:
// Since we are using the updater form of setState now, we need to persist the event.
e.persist();
setQuestion(prev => ({
...prev,
[e.target.name]: prev.topics.includes(e.target.value)
// Return false to remove the part of the array we don't want anymore
? prev.topics.filter((value) => value != e.target.value)
// Create a new array instead of mutating state
: [...prev.topics, e.target.value]
}));
答案 2 :(得分:0)
关于您在codesandbox中的示例,您可以使用以下代码段获得预期的结果
//the idea here is if it exists then remove it otherwise add it to the array.
const handleChange = e => {
let x = data.topics.includes(e.target.value) ? data.topics.filter(item => item !== e.target.value): [...data.topics, e.target.value]
setQuestion({topics:x})
};
因此您可以了解并在您的实际应用程序中实现它。
我注意到您的代码存在的问题是您更改了状态中存储的问题的性质,这使得在下次反应重新渲染时很难获得属性主题。另外,您还直接在改变状态。在可能的情况下,最好始终使用函数数组操纵方法,避免出现map
,filter
和reduce
之类的副作用。