我们如何使用 React 钩子实现 componentWillUnmount? [英] How can we implement componentWillUnmount using react hooks?

查看:47
本文介绍了我们如何使用 React 钩子实现 componentWillUnmount?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The method componentWillUnmount() is invoked immediately before a component is unmounted and destroyed. If we use useEffect with an empty array ([]) as the second argument and put our function in return statement it will be executed after the component is unmounted and even after another component will be mounted. This is done for performance reasons as far as I understand. In order not to delay rendering.

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

So the question is - how can we call some function using hooks before a component gets unmounted?

我想做的是一个应用程序,它在用户输入时保存他的输入(不提交表单).我使用 setInterval 每 N 秒保存更新的文本.而且我需要在卸载组件之前强制保存更新.我不想在导航之前通过反应路由器使用提示.这是一个电子应用程序.对于如何实现此类功能的任何想法或建议,我表示感谢.

What I am trying to do is an application which saves user's input as he types (without submitting form). I use setInterval to save updated text every N seconds. And I need to force save updates before the component will unmount. I don't want to use prompt by react router before navigating. This is an electron application. I appreciate any thoughts or advice on how to implement such functionality.

更新

不幸的是,Effects with Cleanup 在让浏览器运行后运行画.更多细节可以在这里找到:那么清理呢?.它基本上意味着在卸载组件后运行清理,这与在 componentWillUnmount() 中执行代码不同.如果我将 console.log 语句放在清理代码和另一个组件中,我可以清楚地看到调用顺序.问题是我们是否可以在使用钩子卸载组件之前执行一些代码.

Unfortunately, Effects with Cleanup run after letting the browser paint. More details can be found here: So What About Cleanup?. It basically means that cleanup is run after a component is unmounted and it is not the same as executing code in componentWillUnmount(). I can clearly see the sequence of calls if I put console.log statements in the cleanup code and in another component. The question is whether we can execute some code before a component is unmounted using hooks.

更新 2

正如我所见,我应该更好地描述我的用例.让我们想象一个理论上的应用程序,它在 Redux 存储中保存其数据.我们有两个具有某种形式的组件.为简单起见,我们没有任何后端或任何异步逻辑.我们只使用 Redux 存储作为数据存储.

As I can see I should better describe my use case. Let's imagine a theoretical app which holds its data in a Redux store. And we have two components with some forms. For simplicity, we don't have any backend or any async logic. We use only Redux store as data storage.

我们不想在每次击键时更新 Redux 存储.因此,我们将实际值保留在本地组件的状态中,当组件挂载时,我们会使用存储中的值对其进行初始化.我们还创建了一个为 1 设置 setInterval 的效果.

We don't want to update Redux store on every keystroke. So we keep actual values in the local component's state which we initialize with values from the store when a component mounts. We also create an effect which sets up a setInterval for 1s.

我们有以下流程.用户键入一些东西.更新存储在本地组件状态中,直到调用我们的 setInterval 回调.回调只是将数据放入存储中(调度操作).我们将回调放在 useEffect return 语句中,以在组件卸载时强制保存保存,因为我们希望在这种情况下尽快保存要保存的数据.

We have the following process. A User types something. Updates are stored in the local component state until our setInterval callback is called. The callback just puts data in the store (dispatches action). We put our callback in the useEffect return statement to force save to store when the component gets unmounted because we want to save data to store in this case as soon as possible.

当用户在第一个组件中键入内容并立即转到第二个组件(快于 1 秒)时,问题就出现了.由于我们的第一个组件中的清理将在重新渲染后调用,因此在第二个组件安装之前我们的商店不会更新.正因为如此,第二个组件将获得其本地状态的过时值.

The problem comes when a user types something in the first component and immediately goes to the second component (faster than 1s). Since the cleanup in our first component will be called after re-rendering, our store won't be updated before the second component gets mounted. And because of that, the second component will get outdated values to its local state.

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

If we put our callback in componentWillUnmount() it will be called before unmounting and the store will be updated before the next component mounts. So can we implement this using hooks?

推荐答案

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

The question here is how do you run code with hooks BEFORE unmount? The return function with hooks runs AFTER unmount and whilst that doesn’t make a difference for most use cases, their are some where it is a critical difference.

在对此进行了一些调查后,我得出的结论是,当前的 hooks 根本没有提供 componentWillUnmount 的直接替代方案.所以如果你有一个需要它的用例,至少对我来说主要是,非 React 库的集成,你只需要按照旧的方式来做,并使用一个组件.

Having done a bit of investigation on this, I have come to the conclusion that currently hooks simply does not provide a direct alternative to componentWillUnmount. So if you have a use case that needs it, which is mainly for me at least, the integration of non-React libs, you just have to do it the old way and use a component.

更新:请参阅下面关于 UseLayoutEffect() 的答案,看起来它现在解决了这个问题.

Update: see the answer below about UseLayoutEffect() which looks like it now solves this issue.

这篇关于我们如何使用 React 钩子实现 componentWillUnmount?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆