【问题标题】:How can I implement useEffect without repeated mounting and unmounting?如何在不重复安装和卸载的情况下实现 useEffect?
【发布时间】:2021-05-07 01:01:27
【问题描述】:

我想知道是否有更好的方法来实现与以下相同的目标。此代码有效,但它强制此 useEffect 安装和卸载几次,然后才能通过 if 语句,这并不理想。

我有一个如下所示的 useEffect...

useEffect(() => {
    console.log("setNames mounted")
    if (devices !== null && deviceNames !== null){
        setNames(trueDeviceNames(devices.devices, deviceNames.values))
    }
    return ()=> {
        console.log("setNames un-mounted")
    }
}, [devices, deviceNames])

我还有 2 个用于获取数据和 setDevices 和 setDeviceNames 的 useEffects。在他们完成提取并且不再为空之前,我不想运行这个 useEffect。我的代码有效,但肯定有更简洁的方法来实现这一点吗?

【问题讨论】:

  • 这完全没问题,它是用来重置自己的。您可以删除卸载(无用)功能。如果trueDeviceNames 计算量不大,您甚至可以完全删除状态并在渲染阶段调用它。例如<span>{trueDeviceNames(devices.devices, deviceNames.values)}</span>
  • 有趣。我认为有一种更简洁的方法可以做到这一点,因为每次我的依赖项发生变化时都会调用 useEffect。但是,仅在满足条件时设置状态。问题是,如果我有很多 useEffects 被调用但没有通过条件,它可能会导致不必要的安装和卸载导致性能问题,或者奇怪的副作用。
  • 在这种情况下,还有 useMemo 可能比 state 更合适,再加上您优化的依赖项(在您的其他评论中)

标签: reactjs state use-effect


【解决方案1】:

useEffect mount和unmount是在[devices, deviceNames]浅比较的一半,所以函数调用是由于设备或者deviceNames的变化引起的。您可能需要考虑这些值来优化您的 useEffects。

在两个设备的 deviceNames 不等于 null 之前,您的 useEffect 不会导致您的组件重新渲染。

注意 对对象的浅比较使用引用检查 ant 每次更改时都会通过 true。

例如

shallowEqual({value: '1'},  {value: 1}) // false
shallowEqual({value: 1},  {value: 1}) // false
shallowEqual({value:'1'},  {value: '1'}) // false

shallowEqual('1', '1') // true
shallowEqual(1, 1}) // true
shallowEqual('1',  1) // false '1' !== 1

所以你可以通过更精确的依赖数组来优化你的 useEffect

useEffect(() => {
    console.log("setNames mounted")
    if (devices !== null && deviceNames !== null){
        setNames(trueDeviceNames(devices.devices, deviceNames.values))
    }
    return ()=> {
        console.log("setNames un-mounted")
    }
}, [devices && devices.devices, deviceNames && deviceNames.values])

或者如果您确定设备和设备名称是可调用的,您可以编写更简洁的版本

[devices.devices, deviceNames.values])

这些只会通过确切的值更改来更新,并防止大量重新渲染

如果您只想在两个值都存在时调用 useEffect,您可以添加如下依赖项

[Boolean(devices) && Boolean(deviceNames)]

这将是错误的,直到两者都具有真实值并且在启动场景中最多调用 useEffect 2 次​​p>

【讨论】:

  • 感谢您的评论,但我认为您误解了我的问题。但是,它确实使我找到了更好的解决方案。对于依赖项,请使用 [devices && deviceNames]。这确保它不会呈现,直到两者都不再为空。简单的。谢谢
  • 很高兴您找到了解决方案,但是在以下情况下,此 dep 数组可能会导致多次运行映像。首先,两者都为空(第一次调用),然后 deviceNames 获取其实际值,(第二次调用)然后设备获取其值,以及(第三次调用)。这些都是基于不改变这些对象引用(做一些类似记忆的事情)
猜你喜欢
  • 1970-01-01
  • 2018-12-01
  • 1970-01-01
  • 2019-12-13
  • 2020-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-22
相关资源
最近更新 更多