Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我们如何使用react钩子实现componentWillUnmount?_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript 我们如何使用react钩子实现componentWillUnmount?

Javascript 我们如何使用react钩子实现componentWillUnmount?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,方法componentWillUnmount()在卸载和销毁组件之前立即调用。如果我们使用带有空数组([])的useffect作为第二个参数,并将函数放在return语句中,那么它将在卸载组件后执行,甚至在装载另一个组件后也会执行。据我所知,这样做是出于性能原因。为了不延迟渲染 所以问题是-在卸载组件之前,我们如何使用钩子调用某个函数 我试图做的是一个应用程序,它在用户输入时保存用户的输入(不提交表单)。我使用setInterval每N秒保存一次更新的文本。我需要在卸载组件之前强制保存更新。我不

方法
componentWillUnmount()
在卸载和销毁组件之前立即调用。如果我们使用带有空数组([])的
useffect
作为第二个参数,并将函数放在return语句中,那么它将在卸载组件后执行,甚至在装载另一个组件后也会执行。据我所知,这样做是出于性能原因。为了不延迟渲染

所以问题是-在卸载组件之前,我们如何使用钩子调用某个函数

我试图做的是一个应用程序,它在用户输入时保存用户的输入(不提交表单)。我使用setInterval每N秒保存一次更新的文本。我需要在卸载组件之前强制保存更新。我不想在导航前使用react路由器的提示。这是一个电子应用程序。对于如何实现这些功能,我非常感谢您的任何想法或建议

更新

不幸的是,让浏览器绘制后运行。可在此处找到更多详细信息:。它基本上意味着在卸载组件后运行清理,这与在
componentWillUnmount()
中执行代码不同。如果将console.log语句放入清理代码和其他组件中,我可以清楚地看到调用的顺序。问题是我们是否可以在使用钩子卸载组件之前执行一些代码

更新2

如我所见,我应该更好地描述我的用例。让我们想象一个理论应用程序,它将数据保存在Redux存储中。我们有两个部分,有一些形式。为简单起见,我们没有任何后端或任何异步逻辑。我们只使用Redux存储作为数据存储

我们不想在每次击键时都更新Redux存储。因此,我们将实际值保留在本地组件的状态中,当组件挂载时,我们使用存储中的值初始化该状态。我们还创建了一个效果,设置了1s的设置间隔

我们有以下过程。用户输入一些东西。在调用setInterval回调之前,更新存储在本地组件状态。回调只是将数据放入存储(分派操作)。我们将回调放在useffect return语句中,以便在卸载组件时强制保存到存储,因为我们希望在这种情况下尽快将数据保存到存储

当用户在第一个组件中键入某些内容并立即转到第二个组件(快于1s)时,就会出现问题。由于第一个组件中的清理将在重新渲染后调用,因此在第二个组件装入之前不会更新存储。因此,第二个组件将向其本地状态获取过时的值


如果我们将回调放入
componentWillUnmount()
中,它将在卸载之前被调用,并且存储将在下一个组件装载之前更新。那么我们可以使用钩子来实现吗?

组件将卸载可以通过在
useffect
钩子中返回一个函数来模拟。返回的函数将在每次重新提交组件之前调用。严格地说,这是同一件事,但你应该能够模拟任何行为,你想要使用它

useEffect(() => {
  const unsubscribe = api.createSubscription()
  return () => unsubscribe()
})
更新

每次重新加载时,上述操作都将运行。但是,仅模拟装载和卸载时的行为(即componentDidMount和componentWillUnmount)。useEffect接受一个需要为空数组的数组

useEffect(() => {
  const unsubscribe = api.createSubscription()
  return () => unsubscribe()
}, [])

请参阅同一问题的更详细解释。

在卸载组件之前还是之后调用
useffect
返回的函数并不重要:您仍然可以通过闭包访问states valuey:

  const [input, setInput] = useState(() => Store.retrieveInput());

  useEffect(() => {
    return () => Store.storeInput(input); // < you can access "input" here, even if the component unmounted already
  }, []);
const[input,setInput]=useState(()=>Store.retrieveInput());
useffect(()=>{
return()=>Store.storeInput(input);//<
}, []);

如果不在组件状态下管理输入,则整个结构将被破坏,应该在正确的位置更改为管理状态。在您的情况下,您应该将组件的共享输入状态提升到父级。

钩子上的JS文档指定:

效果还可以选择指定如何通过 返回一个函数


因此,您在
useffect
hook中返回的任何函数都将在组件卸载时执行,以及在由于后续渲染而重新运行效果之前执行。

这里的问题是,在卸载之前如何使用hook运行代码?带有钩子的返回函数在卸载后运行,虽然这对大多数用例没有影响,但在某些情况下,它们是一个关键区别

在对此做了一点调查之后,我得出结论,当前的钩子并不能直接替代
组件willunmount
。因此,如果您有一个需要它的用例,至少对我来说主要是非反应libs的集成,那么您只需使用旧的方法并使用一个组件即可


希望这在将来会有所改变

经过一点研究,发现-你仍然可以做到这一点。有点棘手,但应该可以

您可以使用useRef并存储要在闭包(例如render useEffect return callback method)中使用的道具

function Home(props) {
  const val = React.useRef();
  React.useEffect(
    () => {
      val.current = props;
    },
    [props]
  );
  React.useEffect(() => {
    return () => {
      console.log(props, val.current);
    };
  }, []);
  return <div>Home</div>;
}

由于引入了
useLayoutEffect
hook,您现在可以

useLayoutEffect(() => () => {
  // Your code here.
}, [])

要模拟
组件,将卸载
。这在卸载期间运行,但在元素实际离开页面之前。

我同意Frank的观点,但代码需要如下所示,否则它将仅在第一次呈现时运行:

useLayoutEffect(() => {
    return () => {
        // Your code here.
    }
}, [])
这相当于组件将卸载

请阅读。这就是答案。@ArupRaksh
useLayoutEffect(() => {
    return () => {
        // Your code here.
    }
}, [])