我有这个示例代码bellow:
const [data, setData] = useState([{question: '', option: ['']}]);
然后 data 和 setData 将传递给我的组件,例如:
<Question setData={setData} data={data}/>
我的代码内部问题组件是:
const handleAddOption = (questionIndex: number) => {
let newArray = data;
newArray.map((item: any, i: number) => {
if (i === questionIndex) {
newArray[questionIndex].options.push('');
}
});
setData(newArray);
};
问题是,如果我添加一个新的整个对象,它将"刷新"我的页面并显示,但是当我添加像最后一行的代码时,只有一个新的字符串,它不会"重新"渲染"。
有人知道如何解决这个问题?
在反应的第一个经验法则中,请勿直接突变状态。它适用于基于类的组件和setState
,它适用于redux
的还原器,也适用于基于钩的useState
。
您需要
setData((data) => data.map((item, index) => {
if (index !== questionIndex) return item;
return {
...item,
options: [
...item.options,
''
]
};
}));
这里有几个项目要突出显示:
以及基于类的组件的
setState
,可以将回调提供到更新器功能中。我最好在此处详细介绍它。可能建议您提出问题和ReactJS文档。是的,这不是关于钩子,而是使用相同的逻辑。我们需要将旧数据与更改合并,以使我们不想更改的属性仍然存在。这就是所有这些传播操作员几乎没有使用。查看有关react
状态处理阵列的文章最后但并非最不重要的一点是,如果不是我们要更新而没有任何更改,我们就可以直接返回
item
。这使我们确定没有相同的数据可以重新渲染相同的数据。您可能会通过搜索查询"参考平等"来找到其他信息(这是您可能找到的文章之一(。
ps强制更新可能更容易,而不是完全重写代码。但是直接直接突变状态最终会出现不同的难以生产的错误。
您也可能需要更改组件层次结构和数据结构。因此
- 似乎您的错字写
newArray[questionIndex].option.push('');
而不是newArray[questionIndex].options.push('');
- 但是,如果它无助于尝试
forceUpdate();
更多的详细信息,您可以在此答案中找到更多的详细信息,如何强制组件在React中使用钩子重新渲染?或尝试使用此软件包https://github.com/charlesstover/use-force-update
祝你好运:(
粗略实现
我认为您可以更改:
const [data, setData] = useState([{question: '', option: ['']}]);
// into
const [questions, setQuestions] = useState([]);
当您收到新的问题对象时,您可以进行setQuestions([...questions, newQuestion])
。
也就是说,假设您的表格正在收到新问题的输入。如果是这种情况,则在您的 onSubmit
函数中,您可以生成新的问题对象,然后做setQuestions([...questions, newQuestion])
。