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

React中useMemo内调用setState触发非法组件状态更新错误如何解决?

报错原因

useMemo 属于 React 渲染阶段执行的钩子,回调逻辑会在组件渲染过程中同步运行。你的代码在useMemo回调内直接调用父组件传入的setSearchResult修改父组件状态,相当于在SearchCharacters组件还没完成渲染的时候,就触发了父组件Characters的重渲染,违反了React要求渲染过程必须为无副作用纯函数的规则,因此触发非法状态更新警告。
此外,useMemo的设计定位是缓存计算量较大的返回值,本身不应该用来执行修改状态这类副作用操作,属于API误用。

修复方案

方案1:用useEffect替代useMemo执行副作用(改动最小)

useEffect会在组件渲染完成后才执行回调,不会在渲染过程中干扰其他组件状态,同时补全依赖数组的所有依赖项即可:

import React, { useEffect, useState } from "react";
import "./SearchCharacters.css";

function SearchCharacters({ charactersInfo, setSearchResult }) {
  const [searchText, setSearchText] = useState("");
  // 替换useMemo为useEffect
  useEffect(() => {
    const findCharacter = charactersInfo.filter((character) => {
      return (
        character.gender.toLowerCase() === searchText.toLowerCase() ||
        character.species.toLowerCase() === searchText.toLowerCase() ||
        character.status.toLowerCase() === searchText.toLowerCase()
      );
    });
    setSearchResult(findCharacter.length > 0 ? findCharacter : null);
  // 补全所有依赖项
  }, [searchText, charactersInfo, setSearchResult]);

  return (
    <div className="search_container">
      <input
        className="search_input"
        onChange={(e) => setSearchText(e.target.value)}
        placeholder="Enter characters full name"
      />
    </div>
  );
}

export default SearchCharacters;

方案2:状态上移符合单向数据流(更推荐)

将搜索逻辑完全放到父组件实现,子组件仅负责输入控制和传递搜索关键字,不需要直接操作父组件状态:

  • 子组件不再接收setSearchResult,只在searchText变化时通过回调传给父组件
  • 父组件接收searchText后自行用useMemo计算搜索结果,避免跨组件状态修改

方案3:直接返回搜索结果

如果组件结构允许,你可以直接将搜索结果作为useMemo的返回值对外暴露,不需要通过setState跨组件传递,完全规避副作用:

// 子组件内部逻辑
const searchResult = useMemo(() => {
  const findCharacter = charactersInfo.filter((character) => {
    return (
      character.gender.toLowerCase() === searchText.toLowerCase() ||
      character.species.toLowerCase() === searchText.toLowerCase() ||
      character.status.toLowerCase() === searchText.toLowerCase()
    );
  });
  return findCharacter.length > 0 ? findCharacter : null;
}, [searchText, charactersInfo]);
// 父组件可直接读取该返回值使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:06:04