useEffect 是React的一个内置Hook,用于在组件渲染后执行副作用(例如数据获取、订阅或手动更改DOM)。它将在第一次渲染后和每次更新后都会执行。
useEffect(() => {// 这里的代码将在组件挂载和更新时执行。
}, [dependencies]); // dependencies数组控制effect的重新执行。
相比之下,useUpdateEffect 不是React内置的Hook,但这个名称通常被用于自定义Hook,其行为类似于 useEffect,但它不会在组件的首次渲染时执行
,只会在依赖项更新时执行。这可以通过跟踪组件是否已经挂载来实现。以下是如何实现 useUpdateEffect 的一个简单示例:
import { useEffect, useRef } from 'react';function useUpdateEffect(effect, dependencies) {const isInitialMount = useRef(true);useEffect(() => {if (isInitialMount.current) {isInitialMount.current = false;} else {return effect();}}, dependencies);
}
在这个自定义 useUpdateEffect 中,我们使用了 useRef 来追踪组件是否是首次渲染。在首次渲染时,我们不执行传入的 effect 函数,而是将 isInitialMount.current 设置为 false。当组件再次渲染且依赖项发生变化时,由于 isInitialMount.current 已经是 false,我们就执行 effect 函数。
使用 useUpdateEffect 的场景主要是当你想忽略首次渲染的副作用,只关心更新后的副作用时。这在处理像模态对话框关闭或表单值变化等需要响应但不希望初始化时触发的逻辑时非常有用。
实例
import { useEffect, useRef } from "react";export function useIsFirstRender() {const isFirst = useRef(true);if (isFirst.current) {isFirst.current = false;return true;}return isFirst.current;
}export function useUpdateEffect(callback, dependencies) {const isFirstRender = useIsFirstRender();useEffect(() => {if (!isFirstRender) {return callback();} else {}}, dependencies);
}
这里定义了两个自定义的React Hooks:useIsFirstRender 和 useUpdateEffect。
useIsFirstRender
useIsFirstRender 这个Hook的目的是用来检测组件是否处于首次渲染的状态。它使用 useRef 来创建一个可变的 isFirst 引用,该引用在整个组件的生命周期中保持不变。
- const isFirst = useRef(true);: 在初次渲染时,初始化 isFirst.current 为 true。
- 接下来有一个条件判断 if (isFirst.current) { … },如果当前是首次渲染(isFirst.current 为 true),则将其设置为 false 并返回 true。
- 在后续的渲染中,由于 isFirst.current 已经被设置为 false,useIsFirstRender 将会返回 false。
useUpdateEffect
useUpdateEffect 这个Hook类似于 useEffect,但它只在依赖项更新时触发回调,而不会在首次渲染时触发。
- const isFirstRender = useIsFirstRender();: 使用上面定义的useIsFirstRender Hook来检测是否是首次渲染。
2.然后使用 useEffect 来注册一个副作用:
- 在副作用函数内部,通过 if (!isFirstRender) { … } 判断来确保只有在非首次渲染时才执行传入的 callback 函数。
- 如果是首次渲染(isFirstRender 是 true),则不执行任何操作。
- dependencies 参数作为 useEffect 的依赖项数组传递。
这样一来,useUpdateEffect Hook就可以在组件更新时(即依赖项改变时)执行特定行为,而在组件的初始挂载时则不执行任何操作。这在需要避免首次渲染影响和仅希望对更新反应时特别有用。例如,在输入框值改变时进行表单验证,但不想在组件刚挂载时立即验证。