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

为什么useEffect指定users作为依赖后依然每次渲染都无限执行?

问题根因

你代码中的无限循环是逻辑闭环导致的,和性能无关,不需要使用useMemo优化:

  • useEffect监听了users状态,只要users发生变化就会执行内部的getData()方法
  • getData()请求接口后会调用setUsers更新users状态
  • 更新后的users又会触发useEffect重新执行,形成无限循环

你原本将users加入依赖数组的思路本身就不符合需求:排序功能是对本地已有的用户数据做操作,不需要重新请求后端接口,完全不需要让useEffect随users更新触发。

修复步骤
  1. 把useEffect的依赖数组改回空数组[],保证接口仅在组件初始化时请求一次,不会重复触发
  2. 修正排序方法:Array.sort()是原地排序方法,会直接修改原数组,建议先拷贝原数组再排序,避免直接修改状态的不可预期问题
  3. 可选结构优化:表格只需要一个<tbody>标签,不需要循环生成多个tbody
修正后代码
import "./styles.css";
import React, { useState, useEffect } from "react";
import axios from "axios";

export default function App() {
  const [users, setUsers] = useState([]);

  const flattenObj = (obj) => {
    let result = {};
    for (const i in obj) {
      if (typeof obj[i] === "object" && !Array.isArray(obj[i])) {
        const temp = flattenObj(obj[i]);
        for (const j in temp) {
          result[i + "_" + j] = temp[j];
        }
      } else {
        result[i] = obj[i];
      }
    }
    return result;
  };

  // 依赖改回空数组,仅初始化执行一次
  useEffect(() => {
    getData();
  }, []);

  async function getData() {
    try {
      let result = await axios.get("https://randomuser.me/api/?results=20");
      let resultData = result.data.results.map((data) => flattenObj(data));
      setUsers(resultData);
    } catch (err) {
      console.error(err);
    }
  }

  const sortByName = () => {
    // 先拷贝数组再排序,避免修改原状态
    const sorted = [...users].sort((a, b) => a.name_first.localeCompare(b.name_first));
    setUsers(sorted);
  };

  return (
    <div className="App">
      <table>
        <thead>
          <tr>
            <th scope="column" onClick={sortByName}>
              Name
            </th>
            <th scope="column">Location Street Number</th>
            <th scope="column">Location City</th>
          </tr>
        </thead>
        {/* 单个tbody包裹所有行 */}
        <tbody>
          {users.map((value, idx) => {
            return (
              <tr key={idx}>
                <td>{value.name_first}</td>
                <td>{value.location_street_number}</td>
                <td>{value.location_city}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 22:24:05