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

Redux Store触发无限重渲染,组件更新项目列表遇难题求助

问题分析与解决方案

核心问题

  1. 类中使用React Hooks违规:你在MissionService类的构造函数里调用了useAppSelector和useAppDispatch,这违反了React Hooks的规则——Hooks只能在函数组件顶层或自定义Hook中使用,类组件/普通类里用Hooks会导致不可预测的行为。
  2. useEffect无限循环:把projectsList放进依赖数组后,每次调用getProjects都会dispatch更新projectsList,触发组件重渲染,进而再次触发useEffect调用getProjects,形成无限循环。

修复步骤

1. 重构MissionService为自定义Hook

放弃类形式的服务,改用符合React规则的自定义Hook,避免在类中使用Hooks:

import { useAppDispatch } from '../store/hooks';
import { useCallback } from 'react';
import backendAPI from './api';
import { setProjectList } from '../store/slices/xprojSlice';
import { KeycloakInstance } from 'keycloak-js';

export const useMissionService = (keycloak: KeycloakInstance) => {
  const dispatch = useAppDispatch();

  // 用useCallback稳定函数引用,避免不必要的重触发
  const getProjects = useCallback(async () => {
    if (!keycloak.token) return;

    backendAPI.defaults.headers.common['Authorization'] = `Bearer ${keycloak.token}`;

    try {
      const { data } = await backendAPI.get('/mission/user');
      dispatch(setProjectList(data));
    } catch (error: any) {
      errorNotification(error.response.data.message);
    }
  }, [keycloak.token, dispatch]);

  return { getProjects };
};

2. 修正组件中的useEffect逻辑

移除projectsList作为依赖,改为在组件挂载时调用一次getProjects,并在新建项目成功后主动刷新列表:

import { useAppSelector } from '../store/hooks';
import { useMissionService } from './useMissionService';
import { keycloak } from './keycloak'; // 假设你的keycloak实例在这里

const ProjectListComponent = () => {
  const { projectsList } = useAppSelector((state) => state.xproj);
  const { getProjects } = useMissionService(keycloak);

  // 组件挂载时初始化数据
  useEffect(() => {
    getProjects();
  }, [getProjects]); // getProjects已被useCallback稳定,只会触发一次

  // 新建项目的处理函数,成功后主动刷新列表
  const handleCreateProject = async (projectData) => {
    try {
      // 调用新建项目的API
      await backendAPI.post('/mission', projectData);
      // 新建成功后刷新项目列表
      getProjects();
    } catch (error) {
      // 处理新建错误
    }
  };

  return (
    // 组件渲染内容
  );
};

为什么这样有效

  • 自定义Hook遵循了React Hooks的规则,避免了类中使用Hooks的错误。
  • useCallback保证了getProjects的引用稳定,useEffect只会在组件挂载时执行一次初始化请求。
  • 新建项目后主动调用getProjects,既能更新列表,又不会触发无限循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:33:10