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

问题描述 投票:1回答:3

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

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

我想要做的是一个应用程序,在他输入时保存用户的输入(不提交表单)。我每隔N秒使用setInterval来保存更新的文本。我需要在组件卸载之前强制保存更新。我不希望在导航之前使用反应路由器提示。这是一个电子申请。我很欣赏有关如何实现此类功能的任何想法或建议。

更新

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

UPDATE2

我可以看到我应该更好地描述我的用例。让我们设想一个理论应用程序,它将数据保存在Redux商店中。我们有两个组件,有一些形式。为简单起见,我们没有任何后端或任何异步逻辑。我们仅使用Redux存储作为数据存储。

我们不想在每次击键时更新Redux商店。因此,我们将实际值保存在本地组件的状态中,当组件安装时,我们使用商店中的值初始化该状态。我们还创建了一个为1s设置setInterval的效果。

我们有以下过程。用户输入内容。更新存储在本地组件状态,直到调用setInterval回调。回调只是将数据放入商店(调度操作)。我们将回调放在useEffect return语句中,以便在组件卸载时强制保存存储,因为我们希望尽快将数据保存到这种情况。

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

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

javascript reactjs react-hooks
3个回答
5
投票

可以通过在componentWillUnmount钩子内返回一个函数来模拟useEffect。返回的函数将在每次重新呈现组件之前调用。严格来说,这是相同的事情,但你应该能够使用它来模拟你想要的任何行为。

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

查看相同问题here的更详细解释。


1
投票

在卸载组件之前或之后调用useEffect返回的函数无关紧要:您仍然可以通过闭包访问状态值:

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

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

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


0
投票

钩子上的ReactJS文档指定了这个:

效果还可以选择通过返回函数来指定如何“清理”它们。

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

© www.soinside.com 2019 - 2024. All rights reserved.