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

如何用reduce简化React中嵌套forEach的分包商筛选代码?

简化React中分包商筛选条件响应数据的处理逻辑

我需要实现的功能是:从已提交的分包商列表中,提取每个分包商对应**指定筛选条件(criteriaId)**的响应数据。分包商对象包含selectionCriteria数组,每个数组元素包含files、id、request(筛选条件配置)、response(响应值)等字段。目前用嵌套forEach实现,但代码逻辑冗余,想改用reduce或其他更简洁的方式优化这段React代码。

原代码如下:

const { subcontractors } = useLoaderData<typeof loader>();
const { t } = useTranslation();
const submittedSubcontractors = subcontractors.filter(
  (s) => s.status === 'submitted'
);

const subcontractorsResponsesToSelectionCriteria: Array<ISubcontractor> = [];
let providedAnswersResponded: boolean | null = null;
let providedAnswersFiles: Array<IFile> | [] = [];
let providedAnswersRequiresFiles: boolean | null = null;

submittedSubcontractors.forEach((u) => {
  u.selectionCriteria.forEach((c) => {
    if (c.request.id === criteriaId) {
      if (c.response && 'answer' in c.response) {
        if (typeof c.response.answer === 'boolean') {
          providedAnswersResponded = c.response.answer;
        } else {
          providedAnswersResponded = null;
        }
      } else {
        providedAnswersResponded = null;
      }
      providedAnswersFiles = c.files;
      providedAnswersRequiresFiles = c.request.are_files_required;
      subcontractorsResponsesToSelectionCriteria.push(u as ISubcontractor);
    }
  });
});

优化方案1:用reduce实现函数式处理

原代码的核心问题是依赖零散全局变量存储临时值,嵌套forEach的逻辑可读性差。用reduce可以把筛选、匹配、数据提取整合为链式调用,同时消除全局变量:

const { subcontractors } = useLoaderData<typeof loader>();
const { t } = useTranslation();

// 整合所有逻辑:过滤已提交分包商 + 匹配指定筛选条件 + 提取响应数据
const {
  matchedSubcontractors,
  latestResponse: { responded, files, requiresFiles }
} = subcontractors
  .filter(s => s.status === 'submitted')
  .reduce((acc, subcontractor) => {
    // 找到当前分包商中匹配criteriaId的筛选条件项
    const matchedCriteria = subcontractor.selectionCriteria.find(
      c => c.request.id === criteriaId
    );

    if (matchedCriteria) {
      // 提取响应状态(和原逻辑保持一致:仅当answer是布尔值时赋值,否则为null)
      const responded = 
        matchedCriteria.response && 'answer' in matchedCriteria.response && typeof matchedCriteria.response.answer === 'boolean'
          ? matchedCriteria.response.answer
          : null;

      // 更新累加器:添加匹配的分包商,同时覆盖为最新的响应数据
      return {
        matchedSubcontractors: [...acc.matchedSubcontractors, subcontractor],
        latestResponse: {
          responded,
          files: matchedCriteria.files,
          requiresFiles: matchedCriteria.request.are_files_required
        }
      };
    }

    // 无匹配项时返回原累加器
    return acc;
  }, {
    matchedSubcontractors: [] as ISubcontractor[],
    latestResponse: {
      responded: null as boolean | null,
      files: [] as IFile[],
      requiresFiles: null as boolean | null
    }
  });

优化点说明

  1. 消除全局变量:用reduce的累加器统一存储结果,避免零散临时变量
  2. 逻辑分层清晰:链式调用把“筛选已提交分包商”“匹配指定条件”“提取响应数据”拆分为独立步骤
  3. 修复潜在冗余:原代码若一个分包商有多个匹配criteriaId的项,会重复添加分包商;优化后用find只取第一个匹配项,避免重复(若业务确实需要重复添加,可将find改为filter遍历)
  4. 类型安全:保留TypeScript类型定义,避免类型丢失

优化方案2:拆分逻辑为独立函数(高可维护性)

如果追求直观性和可复用性,可以把数据提取逻辑拆为独立函数,保留forEach的简洁性:

const { subcontractors } = useLoaderData<typeof loader>();
const { t } = useTranslation();

// 提取单个筛选条件的响应数据(可复用)
const extractCriteriaResponse = (criteria: typeof subcontractors[0]['selectionCriteria'][0]) => {
  const responded = 
    criteria.response && 'answer' in criteria.response && typeof criteria.response.answer === 'boolean'
      ? criteria.response.answer
      : null;

  return {
    responded,
    files: criteria.files,
    requiresFiles: criteria.request.are_files_required
  };
};

// 主逻辑
const submittedSubcontractors = subcontractors.filter(s => s.status === 'submitted');
const matchedSubcontractors: ISubcontractor[] = [];
let latestResponse = {
  responded: null as boolean | null,
  files: [] as IFile[],
  requiresFiles: null as boolean | null
};

submittedSubcontractors.forEach(sub => {
  const matchedCriteria = sub.selectionCriteria.find(c => c.request.id === criteriaId);
  if (matchedCriteria) {
    matchedSubcontractors.push(sub);
    latestResponse = extractCriteriaResponse(matchedCriteria);
  }
});

这种方式把复杂的条件判断封装为独立函数,主逻辑更易读,同时保留了原代码的执行逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:16:23