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。

相关推荐
kyriewen9 小时前
我扒了 GPT-5.6 的全部编程跑分——有一项 OpenAI 没敢放出来
前端·gpt·ai编程
前端H9 小时前
微前端 v3 架构升级:从加载隔离到状态协同
前端·架构·状态模式
陆枫Larry10 小时前
小程序包体积优化:用 SVG 图片替换 iconfont,并保留 CSS 控色能力
前端
环境栈笔记12 小时前
多账号浏览器选型检查清单:Profile、权限、Session 和任务日志怎么评估
前端·人工智能·后端·自动化
前端炒粉12 小时前
手写promise
java·前端·javascript
LaughingZhu12 小时前
智能体经典范式构建:ReAct、Plan-and-Solve 与 Reflection
前端·react.js·前端框架
jsonbro12 小时前
手把手带你实现发布订阅模式
前端·vue.js·设计模式
一只猫的梦12 小时前
自动化模块 (Automation Module)
前端·chrome
熊猫钓鱼>_>12 小时前
Electron:当 Web 技术统治桌面
大数据·前端·javascript·人工智能·架构·electron·agent
德福危险12 小时前
从盲打xss到到模板注入:unix靶机渗透之Tempus_fugit4
前端·unix·xss