在 useSWR 挂钩中发生变化,未更新 DOM
mutate in useSWR hook not updating the DOM
这是一个 next.js 应用程序,我使用 useSWR
挂钩填充数据。
const { data, error } = useSWR('/api/digest', fetcher, {
revalidateOnFocus: false,
})
问题是 DOM 在下面的 mutate()
行之后没有按预期更新。但是,如果我将数据硬编码为 updatedData
并将其作为 arg 传递给 mutate,它会正常工作。事实上 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,对象仍然是相同的,因此它不会触发 re-render.
我建议您执行类似以下操作,从 data
派生 updatedData
,然后将其传递给 mutate
函数。
const handleAddRowClick = async () => {
const updatedData = {
...data,
subscription: {
...data.subscription,
[selectedCategory]: [
...data.subscription[selectedCategory],
selectedEntity,
]
}
}
mutate('/api/digest', updatedData , false);
}
附带说明一下,您还可以使用 immer 之类的东西来简化复制状态。
这是一个 next.js 应用程序,我使用 useSWR
挂钩填充数据。
const { data, error } = useSWR('/api/digest', fetcher, {
revalidateOnFocus: false,
})
问题是 DOM 在下面的 mutate()
行之后没有按预期更新。但是,如果我将数据硬编码为 updatedData
并将其作为 arg 传递给 mutate,它会正常工作。事实上 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,对象仍然是相同的,因此它不会触发 re-render.
我建议您执行类似以下操作,从 data
派生 updatedData
,然后将其传递给 mutate
函数。
const handleAddRowClick = async () => {
const updatedData = {
...data,
subscription: {
...data.subscription,
[selectedCategory]: [
...data.subscription[selectedCategory],
selectedEntity,
]
}
}
mutate('/api/digest', updatedData , false);
}
附带说明一下,您还可以使用 immer 之类的东西来简化复制状态。