My App

清理

清理

在最后一个模块中,我们讨论了组件实例,以及如何有条件地渲染组件会创建和销毁这些实例。如果你对这个概念仍然感到模糊,可以回顾模块 2 中的“组件实例”课程。

这是视频中的沙盒,添加了清理功能:

import React from 'react';

import MouseTracker from './MouseTracker';

function App() {
  const [isTrackingMouse, setIsTrackingMouse] = React.useState(true);
  
  function toggleMouseTracking() {
    setIsTrackingMouse(!isTrackingMouse);
  }
  
  return (
    <div className="wrapper">
      <button onClick={toggleMouseTracking}>
        Toggle Mouse Tracking
      </button>
      {isTrackingMouse && <MouseTracker />}
    </div>
  );
}

export default App;

返回函数的函数 😬

在我职业生涯早期,让我感到最困惑的事情之一就是函数返回函数。这种事情让我感到头痛:

function doSomething() {
  const hi = 5;
 
  return function () {
    return hi * 2;
  };
}

这里发生的事情与 useEffect 清理 API 类似。我们的主要Effect函数返回一个函数:

React.useEffect(() => {
  // Effect logic here
 
  // Cleanup function:
  return () => {
    // Cleanup logic here
  };
});

好消息是:这实际上更多的是一个实现细节。我们不需要在这个奇怪的语法上过于纠结。

最重要的是你要理解基本的概念:我们给 React 两个函数,一个是Effect函数,一个是清理函数,React 在适当的时机为我们调用这些函数。

话虽如此,设置成这样确实有其合理之处。如果你感兴趣,可以展开这个旁注深入了解:

清理与依赖项

以下是视频中的图表:

运算顺序:

effect-table

快照和清理的视图:

effect-cleanup-timeline

清理函数并不总是提供:

effect-cleanup-timeline-missing-cleanups

最后,这是视频中的沙盒。我调整了按钮的文本,使其更清晰一些:

import React from 'react';

import MouseTracker from './MouseTracker';

function App() {
  return (
    <div className="wrapper">
      <MouseTracker />
    </div>
  );
}

export default App;

React 19 中的 refs 和清理函数

从 React 19 开始,我们之前看到的 ref 属性也可以提供一个清理函数:

<input
  ref={(element) => {
    // This callback will be called on every render
 
    return () => {
      // This cleanup function will be called right before
      // every re-render, and when the element is destroyed.
    };
  }}
/>

就我个人而言,我还没有找到这个的用途。与 useEffect 不同,ref 回调不能给定依赖数组,这意味着 ref 回调 + 清理每次都会触发。

话虽如此,这是一项非常新的变化,也许我还没有找到合适的使用案例。请随意尝试!

您可以在 React 19 补丁说明中了解更多信息。

On this page