在 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,它会正常工作。事实上 dataupdatedData 是一样的。请参阅下面的评论。

编辑:如果我点击任何导航栏 <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 之类的东西来简化复制状态。