useEffect的清洗功能中的变量值是否保持与上次useEffect运行时相同?

时间:2020-04-19 12:23:17

标签: javascript reactjs

我具有此清洁功能:

  // This cleans up our listener and removes us from the latest portal we were in. Is this the right place?
  useEffect(() => {
    return function cleanup() {
      if (!room || !currentPortal) return;
      leavePortal(room, currentPortal, currentUserProfile.uid || uniqueId);
      detachListener();
    };
  }, [isFirstLoad]);

似乎currentPortal的值会像第一次加载时一样增加。当它更改时,我会对其进行控制台记录,但是当组件卸载时,它将使用它具有的初始值。

2 个答案:

答案 0 :(得分:1)

由于仅当isFirsLoad更改时才调用useEffect,因此常规更新为roo。 currentPortal和currentUserProfile不会反映在useEffect清理中。

最简单的解决方案是在任何一个值更改时运行清理

 useEffect(() => {
    return function cleanup() {
      if (!room || !currentPortal) return;
      leavePortal(room, currentPortal, currentUserProfile.uid || uniqueId);
      detachListener();
    };
  }, [isFirstLoad, room, currentPortal,currentUserProfile.uid, uniqueId]);

解决方案是,如果您不希望对每个这些值更改进行清除,请使用ref来存储这些变量

const portalRefs = useRef(null);
useEffect(() => {
    portalRefs.current = { room, currentPortal, uid: currentUserProfile.uid, uniqueId }
}, [room, currentPortal,currentUserProfile.uid, uniqueId])



useEffect(() => {
    return function cleanup() {
      const { room, currentPortal, uid, uniqueId } = portalRefs.current;
      if (!room || !currentPortal) return;
      leavePortal(room, currentPortal, uid || uniqueId);
      detachListener();
    };
  }, [isFirstLoad]);

答案 1 :(得分:1)

请参考(https://reactjs.org/docs/hooks-effect.html

经验丰富的JavaScript开发人员可能会注意到,传递给useEffect的函数在每个渲染器上都会有所不同。这是故意的。实际上,这就是让我们从效果内部读取值的原因,而不必担心它过时。每次重新渲染时,我们都会安排一个不同的效果,以替换上一个效果。在某种程度上,这使效果的行为更像是渲染结果的一部分-每个效果都“属于”特定的渲染。我们将在此页的后面部分更清楚地说明为什么这样做很有用。

您的useEffect依赖项列表为[isFirstLoad],因此每次isFirstLoad更改一个新的效果时,都会创建一个具有捕获的currentPortal值的当前效果。