You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何避免useState默认状态的不必要计算?

解决方案

核心优化:使用useState的初始化函数

针对你不想让复杂初始计算每次渲染都执行、又不想用useEffect的需求,React官方提供了直接的解决方案——给useState传入初始化函数,而非直接传入计算结果。

修改后的代码如下:

import React, { useState } from 'react';
import _ from 'lodash';

type MyRecord = {
  id: string;
  // 20 more props...
};

export default function MyComponent({ records }: { records: Array<MyRecord> }) {
  const [lastPageLoadedIndex, setLastPageLoadedIndex] = useState(0);
  // 将复杂计算逻辑包裹在函数中传给useState
  const [pages, setPages] = useState(() => 
    _.chunk(records, 10).map((chunk, i) => ({
      records: chunk,
      loaded: i === 0,
    }))
  );

  // 修复直接修改state的问题,改用不可变更新方式
  const handleClick = () => {
    setLastPageLoadedIndex(prev => prev + 1);
    setPages(prevPages => {
      const nextIndex = lastPageLoadedIndex + 1;
      if (nextIndex >= prevPages.length) return prevPages;
      return prevPages.map((page, idx) => 
        idx === nextIndex ? { ...page, loaded: true } : page
      );
    });
  };

  return (
    <div>
      {pages
        .flatMap((page) => 
          page.loaded ? page.records.map((record) => (
            <div key={`record-${record.id}`}>
              {record.id}
            </div>
          )) : []
        )}
      <button 
        onClick={handleClick}
        disabled={lastPageLoadedIndex + 1 >= pages.length}
      >Load next</button>
    </div>
  );
}

为什么这个方案可行?

  • React的useState规则:如果传入的是一个函数,这个函数只会在组件首次渲染时执行一次,返回值作为初始state;后续渲染时会直接跳过这个函数,不会重复计算,完美避免了冗余执行。
  • 不需要依赖useEffect,组件只会渲染一次初始状态,不会有额外的二次渲染,对SEO友好。

关于你提到的useMemo方案

用useMemo缓存初始值再传入useState不是理想方案:

  • useMemo的作用是缓存计算结果,依赖变化时会重新执行计算;但你的需求是仅初始化时计算一次,useState的初始化函数本身就具备这个特性,不需要额外的useMemo。
  • 如果records是动态变化的,useMemo会在records更新时重新计算,但这时候你可能需要的是根据新的records重置state,而非仅初始化,这种场景下才需要结合useEffect,但这和你最初的需求不符。

额外优化点

  1. 避免直接修改state:原代码中直接修改pages数组的做法违反了React的不可变状态原则,改用基于prev state的不可变更新(如map或展开运算符),确保React能正确检测状态变化。
  2. 简化渲染逻辑:用flatMap替代map+flat,代码更简洁。
  3. 按钮禁用逻辑:添加disabled属性,防止用户点击超出页数的按钮。

内容的提问来源于stack exchange,提问作者Alien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 15:31:08