React Hooks:“useMutationEffect”和“useLayoutEffect”有什么区别

reactjs

1个回答

写回答

余小碗

2025-06-22 22:50

+ 关注

Java
Java

使用 React Hooks 可以方便地在函数组件中进行状态管理和副作用操作。React 提供了多个 Hooks,其中包括了两个非常相似的 Hooks:useMutationEffect 和 useLayoutEffect。这两个 Hooks 都是在组件完成渲染之后执行副作用操作的,但它们之间有一些关键的区别。

useMutationEffect vs useLayoutEffect

在介绍这两个 Hooks 的区别之前,我们先来了解一下它们的相似之处。useMutationEffect 和 useLayoutEffect 都可以在组件完成渲染之后执行副作用操作,它们的调用时机与 componentDidMount 和 componentDidUpdate 生命周期方法相似。这意味着我们可以在这两个 Hooks 中执行一些需要等待渲染完成之后再进行的操作,比如操作 DOM。

然而,useMutationEffect 和 useLayoutEffect 之间的主要区别在于它们在 React 重新渲染组件时的调用时机。useMutationEffect 会在所有 DOM 变更之后同步调用,而 useLayoutEffect 则会在浏览器绘制之前同步调用。这意味着 useLayoutEffect 的执行时机更早,可以在 DOM 渲染之前同步更新 DOM。

useMutationEffect 示例

下面我们来看一个使用 useMutationEffect 的示例代码。假设我们有一个计数器组件,每次点击按钮时,计数值会增加。

Javascript

import React, { useState, useMutationEffect } from "react";

function Counter() {

const [count, setcount] = useState(0);

useMutationEffect(() => {

// DOM 变更操作

document.title = <code>Count: ${count}</code>;

}, [count]);

return (

<div>

Count: {count}

<button onClick={() => setcount(count + 1)}>Increment</button>

</div>

);

}

export default Counter;

在上面的代码中,我们使用了 useMutationEffect 来更新文档标题,使其显示当前的计数值。每当 count 发生变化时,useMutationEffect 会同步执行 DOM 变更操作,更新文档标题。

useLayoutEffect 示例

接下来,我们来看一个使用 useLayoutEffect 的示例代码。假设我们有一个 TodoList 组件,每次添加新的 Todo 时,我们想要将滚动条滚动到底部。

Javascript

import React, { useState, useLayoutEffect } from "react";

function TodoList() {

const [todos, setTodos] = useState([]);

const [newTodo, setNewTodo] = useState("");

useLayoutEffect(() => {

// DOM 变更操作

const list = document.getElementById("todo-list");

list.scrollTop = list.scrollHeight;

}, [todos]);

const addTodo = () => {

setTodos([...todos, newTodo]);

setNewTodo("");

};

return (

<div>

<ul id="todo-list">

{todos.map((todo, index) => (

<li key={index}>{todo}</li>

))}

</ul>

<input value={newTodo} onChange={(e) => setNewTodo(e.target.value)} />

<button onClick={addTodo}>Add Todo</button>

</div>

);

}

export default TodoList;

在这个示例中,我们使用了 useLayoutEffect 来在添加新的 Todo 后将滚动条滚动到底部。每当 todos 数组发生变化时,useLayoutEffect 会同步执行 DOM 变更操作,将滚动条滚动到底部。

在 React Hooks 中,useMutationEffect 和 useLayoutEffect 都可以用于在组件完成渲染之后执行副作用操作,但它们在调用时机上有所不同。useMutationEffect 会在所有 DOM 变更之后同步调用,而 useLayoutEffect 则会在浏览器绘制之前同步调用。根据具体的需求,我们可以选择使用适合的 Hooks 来进行操作。

举报有用(4分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号