这是一个next.js应用程序,我使用useSWR
钩子填充数据。
const { data, error } = useSWR('/api/digest', fetcher, {
revalidateOnFocus: false,
})
问题是,在下面的mutate()
行之后,DOM没有按预期更新。但是,如果我将数据硬编码为updatedData
,并将其作为mutate的arg传递,它将正常工作。事实是data
和updatedData
是相同的。请参阅下面的评论。
编辑:如果我点击任何导航栏<Link/>
,它会被更新。
有发生什么的线索吗?
const handleAddRowClick = async () => {
const newRow = { category: selectedCategory, entity: selectedEntity }
data.subscription[selectedCategory].push(selectedEntity);
console.log(data); // This data is equal to updatedData
const updatedData = {
"subscription": {
"materialFact": [
"Boeing"
],
"headlines": [
"thejournal",
"onemagazine" // ***This is the value added.
]
}
}
// mutate('/api/digest', data, false) // This does not works.
mutate('/api/digest', updatedData , false) // It works.
}
我假设您在handleAddRowClick
中使用的data
属性与您从useSWR
中获得的属性相同。现在,如果在data
中更新一些深度嵌套的对象,它不会更改数据引用。它仍然指向旧对象。因此,如果再次将其传递给mutate
,对于mutate,对象仍然相同,因此不会触发重新渲染。
我建议您执行以下操作,从data
派生updatedData
,然后将其传递给mutate
函数。
const handleAddRowClick = async () => {
const updatedData = {
...data,
subscription: {
...data.subscription,
[selectedCategory]: [
...data.subscription[selectedCategory],
selectedEntity,
]
}
}
mutate('/api/digest', updatedData , false);
}
顺便说一句,你也可以使用类似immer的东西来简化复制状态。