reactjs 当对象属性在依赖数组中时,useEffect不触发

vsikbqxv  于 2022-12-22  发布在  React
关注(0)|答案(4)|浏览(382)

我有一个context/provider,它有一个WebSocket作为状态变量。一旦socket被初始化,onMessage回调就被设置。回调如下所示:

const wsOnMessage = (message: any) => {
    const data = JSON.parse(message.data);
    setProgress(merge(progress, data.progress));
};

在组件中,我有这样的内容:

function PVCListTableRow(props: any) {
    const { pvc } = props;
    const { progress } = useMyContext();

    useEffect(() => {
        console.log('Progress', progress[pvc.metadata.uid])
    }, [progress[pvc.metadata.uid]])

    return (
        {/* stuff */}
    );

}

但是,当progress变量更新时,效果不会触发。
progress变量的数据结构如下所示

{
    "uid-here": 0.25,
    "another-uid-here": 0.72,
    ...etc,
}

当与pvc.metadata.uid匹配的属性更新时,如何触发useEffect?
或者,当该值被更新时,我如何让组件重新呈现?

djmepvbi

djmepvbi1#

引用文件:
传递给useEffect的函数将在渲染提交到屏幕后运行。
这是关键部分(许多人似乎忽略了):使用提供给useEffect的依赖性列表来 * 限制 * 其调用,但不设置"提交呈现之后“之外的某些条件。
换句话说,如果React认为您的组件没有更新,那么useEffect钩子就不会被调用!
现在,从您的问题中还不清楚您的上下文(progress)到底是什么样子的,但是这一行:

setProgress(merge(progress, data.progress));

......非常可疑。
请参见,要让React跟踪 object 中的更改,该对象的引用应该更改。现在,setProgress很可能只是将值(作为参数传递)赋给变量,而不执行任何克隆,无论是浅克隆还是深克隆。
然而,如果代码中的mergelodash.merge相似(同样,很有可能它实际上是lodash.merge; JS生态系统现在不是很大),它不会返回一个新对象;而是将值从data.progress重新分配到progress,并且返回后者
很容易检查:将上述一行改为.

setProgress({ ...merge(progress, data.progress) });

现在,在本例中将创建一个新对象,并将其值传递给setProgress。当然,你可以在那里做一些检查,看看你是否真的应该强制值更新,但是即使没有这些检查,它也应该有足够的性能。

ecfsfe2w

ecfsfe2w2#

似乎没有问题...你确定pvc.metadata.uid键在progress对象中吗?

  • 另一点:将依赖项移动到一个单独变量中,然后将其放入依赖项数组中。
slhcrj9b

slhcrj9b3#

Spread操作符创建一个新的引用,因此它将触发渲染

let updated = {...property};
updated[propertyname] =value;
setProperty(()=>updated);

如果只使用下面的代码段,则不会重新呈现

let updated = property; //here property is the base object 
updated[propertyname] = value;
setProperty(()=>updated);
egdjgwm8

egdjgwm84#

尝试[progress['pvc.metadata.uid']]

function PVCListTableRow(props: any) {
    const { pvc } = props;
    const { progress } = useMyContext();

    useEffect(() => {
        console.log('Progress', progress[pvc.metadata.uid])
    }, [progress['pvc.metadata.uid']])

    return (
        {/* stuff */}
    );

}

相关问题