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

React中使用useState时如何避免无关状态变更引发的列表重渲染?

解决方案

问题根本原因

React组件只要自身状态、接收的props、绑定的context发生变更,就会触发整个组件的全量重渲染。你当前的列表渲染逻辑直接写在App组件内部,count是App的内部状态,count更新时App组件会整体重渲染,列表的map逻辑自然会重新执行,触发不必要的计算。

具体实现方案

核心思路是把列表模块抽为独立组件,配合React.memo做渲染缓存,只有当列表依赖的repos属性发生变化时,才会触发列表组件的重渲染。

改造步骤

  • 拆分独立的RepoList组件,用React.memo包裹,组件只接收repos作为入参
  • 把原App组件中列表渲染的逻辑迁移到RepoList组件中
  • App组件中只需要把repos作为属性传递给RepoList即可

改造后完整代码

import "./styles.css";
import { Fragment, useEffect, useState, memo } from "react";

// 拆分独立列表组件,用memo包裹做渲染缓存
const RepoList = memo(({ repos }) => {
  return (
    <div className="App">
      {repos.map((r) => {
        console.log("render");
        return <li key={r.id}>{r.name}</li>;
      })}
    </div>
  )
})

const App = () => {
  const [repos, setRepos] = useState([]);
  const [count, setCount] = useState(1);

  useEffect(() => {
    const fetchRepos = async () => {
      const response = await fetch("https://api.github.com/repositories");
      const repoDetails = await response.json();
      console.log(repoDetails);
      setRepos([...repoDetails]);
    };
    fetchRepos();
  }, []);

  const handleCount = () => {
    setCount(count + 1);
  };

  return (
    <Fragment>
      <RepoList repos={repos} />
      <button onClick={handleCount}>Button {count}</button>
    </Fragment>
  );
};

export default App;

补充说明

如果后续需要给RepoList传递回调函数作为属性,需要配合useCallback缓存回调函数,避免因为回调引用变化导致memo缓存失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 20:24:04