React中的useMemo 和 useEffect 哪个先执行?

在 React 组件的渲染过程中,useMemo 和 useEffect 的执行顺序是不同的。具体来说:

  1. useMemo 先执行:useMemo 是在 渲染阶段 执行的,它的作用是缓存计算结果,确保在渲染过程中可以直接使用缓存的值。

  2. useEffect 后执行:useEffect 是在 提交阶段 执行的,它的作用是处理副作用(如数据获取、DOM 操作等),并且是在 DOM 更新之后才运行。

详细执行顺序

  1. 组件渲染阶段:
  • React 调用组件的渲染方法(函数组件的函数体或类组件的 render 方法)。

  • 在渲染过程中,useMemo 会被执行,计算并缓存值。

  • 如果依赖项没有变化,useMemo 会直接返回缓存的值,避免重复计算。

  1. DOM 更新阶段:
  • React 将组件的渲染结果应用到 DOM 上,更新 UI。
  1. 提交阶段:
  • 在 DOM 更新完成后,React 会执行 useEffect 中的副作用函数。

  • 如果 useEffect 有清理函数(返回的函数),它会在组件卸载或依赖项变化时执行。

示例代码

javascript 复制代码
import React, { useMemo, useEffect, useState } from 'react';

function MyComponent({ a, b }) {
  // useEffect 写在 useMemo 上面
  useEffect(() => {
    console.log('useEffect: Side effect after DOM update');
    return () => {
      console.log('useEffect: Cleanup');
    };
  }, [a, b]);

  // useMemo 写在 useEffect 下面
  const memoizedValue = useMemo(() => {
    console.log('useMemo: Calculating expensive value...');
    return a + b;
  }, [a, b]);

  console.log('Render: Component rendering...');

  return (
    <div>
      <p>Memoized Value: {memoizedValue}</p>
    </div>
  );
}

function App() {
  const [a, setA] = useState(1);
  const [b, setB] = useState(2);

  return (
    <div>
      <MyComponent a={a} b={b} />
      <button onClick={() => setA(a + 1)}>Increment A</button>
      <button onClick={() => setB(b + 1)}>Increment B</button>
    </div>
  );
}

控制台输出顺序

  1. 当组件首次渲染时:
bash 复制代码
Render: Component rendering...
useMemo: Calculating expensive value...
useEffect: Side effect after DOM update
  1. 当 a 或 b 变化时:
bash 复制代码
Render: Component rendering...
useMemo: Calculating expensive value...
useEffect: Cleanup
useEffect: Side effect after DOM update

总结

  • useMemo 在渲染阶段执行:无论它写在 useEffect 上面还是下面,它都会在组件渲染时执行。

  • useEffect 在提交阶段执行:它总是在 DOM 更新后执行,与代码书写顺序无关。

  • React 的执行顺序是固定的:useMemo 先执行,useEffect 后执行。

如果你需要在渲染阶段避免昂贵的计算,使用 useMemo;如果你需要在 DOM 更新后执行某些操作(如数据获取或订阅),使用 useEffect。

相关推荐
AC赳赳老秦28 分钟前
CSDN 技术社区数据采集:OpenClaw 抓取公开技术热帖,生成领域技术热点周报
java·大数据·前端·数据库·python·php·openclaw
结网的兔子36 分钟前
【前端开发】Web端迁移至 uni-app 及鸿蒙扩展方案对比
前端·uni-app·harmonyos
水瓶夜之1 小时前
.NET 中的新增功能系列文章——.NET SDK中的新增功能
前端·chrome·.net
笨笨狗吞噬者2 小时前
VS Code 内置浏览器打开网页
前端
SamChan902 小时前
WebSocket实现PDF翻译进度实时推送:Go后端+React前端的完整方案
前端·websocket·pdf·c#·react·机器翻译
甲维斯2 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·人工智能
奈斯先生Vector2 小时前
大模型 Agentic Workflow 架构解构:异构 API 调度与 Token 路由的多模态系统设计
开发语言·前端·架构·prompt·aigc·音视频
海带紫菜菠萝汤2 小时前
FFmpeg.wasm 实践:在浏览器中运行 FFmpeg 的能力边界与性能瓶颈
前端·javascript·ffmpeg·音视频·wasm
名字还没想好☜2 小时前
React 受控输入框光标跳到末尾:格式化输入时的 selection 丢失 bug 与修复
前端·javascript·react.js·bug·react·next.js
Access开发易登软件2 小时前
Access 怎么做前后端分离?用 Web API 读写 SQL Server
前端·数据库·人工智能·microsoft·excel·access