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

React中用useState赋值自定义Hook数据时触发过多重渲染错误的问询

解决React无限重渲染问题:将useFetch数据存入state

问题根源

你直接在组件函数体中调用setUsers(data),组件每次渲染都会执行这段代码——而setUsers会触发组件重新渲染,最终形成渲染→调用setUsers→重新渲染→再调用setUsers的无限循环,触发React的重渲染限制报错。


解决方案1:用useEffect同步数据

通过useEffect监听data的变化,仅当data更新时才同步到users状态,避免无意义的重复更新:

import React, { useState, useEffect } from "react";
import useFetch from "./fetchData";
import Users from "./Users";
import Search from "./Search"; // 补充导入Search组件

const ASSIGN5 = () => {
  const [users, setUsers] = useState([]);
  // 统一useFetch返回的isloading命名为isLoading(避免大小写不一致问题)
  const { data, isloading: isLoading, error } = useFetch(
    "https://jsonplaceholder.typicode.com/users"
  );

  // 仅当data变化时,同步到users状态
  useEffect(() => {
    if (data?.length) {
      setUsers(data);
    }
  }, [data]);

  // 实现搜索过滤逻辑
  const handleSearch = (searchTerm) => {
    const filteredUsers = data.filter(user => 
      user.name.toLowerCase().includes(searchTerm.toLowerCase())
    );
    setUsers(filteredUsers);
  };

  return (
    <div className="container">
      <h1>Users Management App</h1>
      {isLoading && <p>Loading users...</p>}
      {error && <p>{error}</p>}

      <Search onHandleSearch={handleSearch} />
      {users.length > 0 && <Users users={users} />}
    </div>
  );
};

export default ASSIGN5;

解决方案2:用useMemo直接计算过滤结果(更优)

不需要把原始数据同步到users状态,而是维护搜索关键词的state,结合useMemo实时计算过滤后的结果,减少不必要的state更新:

import React, { useState, useMemo } from "react";
import useFetch from "./fetchData";
import Users from "./Users";
import Search from "./Search";

const ASSIGN5 = () => {
  const [searchTerm, setSearchTerm] = useState("");
  const { data, isloading: isLoading, error } = useFetch(
    "https://jsonplaceholder.typicode.com/users"
  );

  // 缓存过滤结果,仅当data或searchTerm变化时重新计算
  const filteredUsers = useMemo(() => {
    if (!data) return [];
    return data.filter(user => 
      user.name.toLowerCase().includes(searchTerm.toLowerCase())
    );
  }, [data, searchTerm]);

  const handleSearch = (term) => {
    setSearchTerm(term);
  };

  return (
    <div className="container">
      <h1>Users Management App</h1>
      {isLoading && <p>Loading users...</p>}
      {error && <p>{error}</p>}

      <Search onHandleSearch={handleSearch} />
      {filteredUsers.length > 0 && <Users users={filteredUsers} />}
    </div>
  );
};

export default ASSIGN5;

额外注意点

  • 修正了useFetch中isloading与组件内isLoading的大小写不一致问题,避免Loading状态不生效;
  • 方案2利用useMemo缓存计算结果,性能更优,推荐优先使用;方案1适合需要对users进行多步修改的复杂场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:40:43