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

如何用useSWR动态获取更新的roleIds列表数据并避免循环渲染

解决动态多选角色时批量获取权限数据的问题

核心问题分析

你的当前实现存在两个关键问题:

  • fetcher 返回的是Promise数组,SWR会直接将这个数组作为data返回,导致你需要手动处理异步解析,但异步操作完成前privilegeData已经被返回,永远拿不到有效数据。
  • 每次Hook执行时都会创建新的privilegeData数组,可能引发不必要的组件重渲染,甚至潜在的无限循环风险。

解决方案

1. 修正Fetcher函数

让fetcher返回单个Promise,内部用Promise.all批量请求并解析所有结果,这样SWR会直接返回已解析的结果数组,无需手动处理Promise:

export const fetcher = (urls: string[]) => 
  Promise.all(urls.map(url => AuthenticatedAPIInstance.get(url).then(res => res.data)))

2. 重构自定义Hook

  • 用useMemo缓存privilegeData,仅当data或roleIds变化时重新计算,避免不必要的重渲染。
  • 直接使用SWR返回的已解析data,无需再处理异步Promise。
  • 空数组时跳过请求,减少无效API调用。
import { useSWR } from 'swr';
import { useMemo } from 'react';

export const useMultipleRolePrivileges = (roleIds: (string | number)[]) => {
  console.log("request made for these roles", roleIds);
  
  // 缓存URL数组,仅当roleIds变化时重新生成
  const urls = useMemo(() => 
    roleIds.map(roleId => `/role_privileges?role_id=${roleId}`), 
    [roleIds]
  );

  // 空数组时不发起请求
  const { data, error } = useSWR(urls.length > 0 ? urls : null, fetcher);

  // 缓存处理后的数据,同步roleIds的增删变化
  const privilegeData = useMemo(() => {
    if (!data) return [];
    return data.map((value, index) => ({
      value,
      id: roleIds[index]
    }));
  }, [data, roleIds]);

  const loading = !data && !error;

  return {
    loading,
    privilegeData,
    error
  };
};

3. 组件中的优化使用

简化changeHandler逻辑,确保trialIds是React状态变量:

import { useState } from 'react';

const [trialIds, setTrialIds] = useState<(string | number)[]>([]);

const { loading: rolePrivilegesLoading, privilegeData: rolePrivileges } = useMultipleRolePrivileges(trialIds);

const changeHandler = (e: React.ChangeEvent<HTMLSelectElement>) => {
  const selectedIds = Array.from(e.selectedOptions).map(opt => opt.value);
  setTrialIds(selectedIds);
};

额外优化点

  • 缓存复用:SWR会自动缓存请求结果,当重新添加已选过的角色ID时,直接复用缓存,无需重复请求。
  • 类型安全:替换any为具体类型(如string[]或number[]),提升代码可维护性。
  • 错误处理:返回error状态,方便组件中处理请求失败的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 22:02:54