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

如何在Company Reducer中更新状态并仅返回单个公司对象?

解答

我明白你的困惑了——这里其实是把reducer的状态更新职责和组件需要的数据格式搞混啦。

首先得明确:Reducer的核心作用是维护整个应用的状态对象,它必须返回完整的state,而不是单个数据。你的需求(缓存已获取的公司,避免重复请求)本身是合理的,只是当前的reducer有个小问题:会重复添加同一个公司到数组里,另外组件需要学会从缓存的数组里提取单个公司。

第一步:修复Reducer的重复添加问题

当前的GET_COMPANY处理会直接把新公司加到数组头部,不管是否已经存在。我们需要先检查缓存里有没有这个公司,只有不存在的时候才添加:

const initialState = { companies: [] };
export default (state = initialState, action) => {
  switch (action.type) {
    case GET_COMPANIES:
      // 如果是获取所有公司的逻辑,这里应该把payload替换整个数组,比如:
      // return { ...state, companies: action.payload };
      return { ...state };
    case GET_COMPANY:
      // 检查当前缓存中是否已有该公司(假设公司对象有name属性匹配路由参数)
      const companyExists = state.companies.some(
        comp => comp.name === action.payload.name
      );
      if (companyExists) {
        // 已存在,直接返回原状态
        return state;
      }
      // 不存在,添加到缓存数组
      return { 
        ...state, 
        companies: [...state.companies, action.payload] 
      };
    default:
      return state;
  }
};

第二步:组件中获取单个公司

Reducer维护了完整的缓存数组,但组件只需要当前路由对应的单个公司。你可以在组件中用useSelector(如果是React Redux)从状态里筛选出目标公司:

import { useSelector, useDispatch } from 'react-redux';
import { useParams, useEffect } from 'react-router-dom';
import { getCompany } from './your-action-file-path';

const CompanyPage = () => {
  const { name } = useParams();
  const dispatch = useDispatch();
  const targetCompany = useSelector(state => 
    state.company.companies.find(comp => comp.name === name)
  );

  // 根据缓存是否存在,决定是否触发API请求
  useEffect(() => {
    if (!targetCompany) {
      dispatch(getCompany(name));
    }
  }, [name, targetCompany, dispatch]);

  if (!targetCompany) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <h1>{targetCompany.name}</h1>
      {/* 渲染公司详情内容 */}
    </div>
  );
};

进阶优化:把缓存数组改成对象(更高效)

如果公司数量较多,数组查找会比较慢,建议把companies改成以公司name为键的对象,这样查找单个公司的时间复杂度是O(1):

// 初始状态调整
const initialState = { companies: {} };

// Reducer中的GET_COMPANY处理
case GET_COMPANY:
  const { name } = action.payload;
  // 检查是否已缓存,已存在则直接返回原状态
  if (state.companies[name]) {
    return state;
  }
  // 不存在则添加到缓存对象
  return {
    ...state,
    companies: {
      ...state.companies,
      [name]: action.payload
    }
  };

// 组件中获取的方式也更简单
const targetCompany = useSelector(state => state.company.companies[name]);

这样既满足了缓存需求,又能让组件快速获取到单个公司数据——Reducer依然负责维护完整的状态,组件则按需提取自己需要的数据,这才是Redux的正确使用方式~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:17:29