精简版映射:源码系列 4 之效应依赖清理流程
2023-11-20 16:31:17
源码系列 4:效应依赖清理流程
在源码系列的第四部分,我们将重点探索精简版映射中的效应依赖清理流程。我们首先回顾效应的概念,理解效应依赖的含义,然后深入研究如何创建并销毁效应及其依赖关系,从而揭开精简版映射的内部运作机制。
效应
在 React 中,效应是指任何可以导致组件状态改变的操作,例如设置计时器、发送网络请求或订阅事件等。这些操作通常在组件挂载或更新时执行,并且可能会在组件卸载时销毁。
效应依赖
效应依赖是指效应所需的任何数据或状态。当效应依赖发生变化时,效应需要重新执行。例如,如果一个效应依赖于组件的某个状态,那么当该状态发生变化时,该效应就会重新执行。
效应依赖清理流程
效应依赖清理流程是指在组件卸载时销毁效应及其依赖关系的过程。这个过程对于防止内存泄漏和确保组件正确卸载至关重要。
创建效应
在创建效应时,我们需要指定效应的依赖关系。我们可以通过使用 useEffect
钩子函数来创建效应,并通过 useEffect
的第二个参数来指定效应的依赖关系。例如,以下代码创建一个效应,该效应会在组件挂载时设置一个计时器,并在组件卸载时销毁该计时器:
import { useEffect } from 'react';
const MyComponent = () => {
useEffect(() => {
const timer = setTimeout(() => {
console.log('Hello, world!');
}, 1000);
return () => {
clearTimeout(timer);
};
}, []);
return <div>Hello, world!</div>;
};
在这个示例中,效应的依赖关系是一个空数组 []
,这意味着该效应仅在组件挂载时执行一次。如果我们将 []
替换为 [count]
,则该效应会在组件挂载时执行一次,并且每当 count
状态发生变化时都会重新执行。
销毁效应
在组件卸载时,我们需要销毁效应及其依赖关系。我们可以通过在 useEffect
的第二个参数中返回一个函数来销毁效应。例如,以下代码创建一个效应,该效应会在组件挂载时设置一个计时器,并在组件卸载时销毁该计时器:
import { useEffect } from 'react';
const MyComponent = () => {
useEffect(() => {
const timer = setTimeout(() => {
console.log('Hello, world!');
}, 1000);
return () => {
clearTimeout(timer);
};
}, []);
return <div>Hello, world!</div>;
};
在这个示例中,效应的依赖关系是一个空数组 []
,这意味着该效应仅在组件挂载时执行一次。如果我们将 []
替换为 [count]
,则该效应会在组件挂载时执行一次,并且每当 count
状态发生变化时都会重新执行。
精简版映射中的效应依赖清理流程
在精简版映射中,效应依赖清理流程与上述流程基本相同。唯一不同的是,精简版映射中的效应依赖清理流程是在精简版映射的 prune
方法中执行的。
prune
方法会遍历精简版映射中的所有键,并检查每个键的依赖关系是否发生变化。如果某个键的依赖关系发生变化,那么该键对应的效应就会被销毁。
例如,以下代码创建一个精简版映射,该映射包含一个键 count
,其值是一个效应。该效应会在组件挂载时设置一个计时器,并在组件卸载时销毁该计时器:
import { useMemo } from 'react';
const MyComponent = () => {
const map = useMemo(() => {
const map = new Map();
map.set('count', {
effect: () => {
const timer = setTimeout(() => {
console.log('Hello, world!');
}, 1000);
return () => {
clearTimeout(timer);
};
},
dependencies: [],
});
return map;
}, []);
return <div>Hello, world!</div>;
};
在这个示例中,效应的依赖关系是一个空数组 []
,这意味着该效应仅在组件挂载时执行一次。如果我们将 []
替换为 [count]
,则该效应会在组件挂载时执行一次,并且每当 count
状态发生变化时都会重新执行。
当组件卸载时,prune
方法会遍历精简版映射中的所有键,并检查每个键的依赖关系是否发生变化。如果 count
键的依赖关系发生变化,那么该键对应的效应就会被销毁。
总结
效应依赖清理流程对于防止内存泄漏和确保组件正确卸载至关重要。精简版映射中的效应依赖清理流程与上述流程基本相同,唯一不同的是,精简版映射中的效应依赖清理流程是在精简版映射的 prune
方法中执行的。