React.useState与动画和useEffect

4
我正在尝试使用useState和useEffect实现包装组件的动画效果。如果props上的某个值发生改变,我希望它能触发动画的开始:
const propVal = getter(props);
const mounted = useRef(true);
useEffect(() => {
  //code to initialize and start animation removed

  //because a started animation uses requestAnimationFrame
  //a component may want to set state for animation while not
  //mounted anymore, prevent the error by setting mounted to false
  return () => (mounted.current = false);
}, [propVal]);//<--if propVal changes the animation starts

完整代码在这里

propVal可以是一个项目的ID(新项目将带有动画效果),也可以是名为deleted的属性,表示已删除项目(应该带有动画效果)。

我正在尝试创建一个更小的代码示例来重现我所面临的问题,但尚未能够做到。

问题是,如果我删除一个项目,那么即使组件没有卸载,mounted.current = false(从useEffect返回的回调)部分也会被调用。

当我将代码更改为return () => false && (mounted.current = false);,基本上是删除了防护措施以防止未安装的组件进行动画处理,然后删除项目将会出现动画而不会出错。这告诉我组件没有被卸载,但是某种方式触发了返回的onUnmount的回调函数。

很抱歉目前还无法提供更简单的问题复现,也许有人知道当组件显然没有卸载时为什么会调用回调函数。

1个回答

1
如果我理解正确,您应该在effect中将mounted ref设置为true。 否则,对propVal依赖的任何更改都将使recurAnimate停止工作。
比如值从id =>更改为“删除”, 清理效果会运行,但组件不会卸载, 然后效果再次运行新值,但isMounted引用 保持recurAnimate被锁定。
编辑:从effect返回的清理函数!== componentWillUnmount。 它将在每次重新运行效果时运行,最后在组件卸载时运行。

谢谢您的回复,我看到返回的“cleanup”函数被多次调用,而不仅仅是在卸载时。它说:“此外,如果组件多次渲染(通常会这样做),则在执行下一个 effect 之前会清除上一个 effect。”。您的答案帮助我解决了问题,而无需使用 useRef,并且可以以这种方式完成。 - HMR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接