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

React Apollo GraphQL:如何在组件间共享数据转换逻辑

解决Apollo GraphQL React应用中重复数据转换的问题

方案1:封装带缓存转换逻辑的自定义Hook

将查询与高成本的转换逻辑封装到自定义Hook中,借助useMemo缓存转换结果,只有当原始查询数据更新时才重新执行转换。多个组件调用该Hook时会共享缓存后的转换值。

import { useQuery, gql } from '@apollo/client';
import { useMemo } from 'react';

// 定义GraphQL查询
const GET_DATA_QUERY = gql`
  query GetData {
    items {
      id
      rawField1
      rawField2
    }
  }
`;

// 高成本的转换函数
const transformRawData = (rawData) => {
  return rawData.items.map(item => ({
    id: item.id,
    combinedField: `${item.rawField1}_${item.rawField2}`,
    // 其他复杂转换逻辑...
  }));
};

// 自定义Hook
export const useTransformedData = () => {
  const { data, loading, error } = useQuery(GET_DATA_QUERY);
  
  // 缓存转换结果,仅当data变化时重新计算
  const transformedData = useMemo(() => {
    if (!data) return [];
    return transformRawData(data);
  }, [data]);

  return { transformedData, loading, error };
};

组件中直接使用该Hook即可:

// 组件A
const ComponentA = () => {
  const { transformedData, loading } = useTransformedData();
  if (loading) return <div>Loading...</div>;
  return (
    <div>
      {transformedData.map(item => (
        <div key={item.id}>{item.combinedField}</div>
      ))}
    </div>
  );
};

// 组件B调用同一个Hook,自动共享转换结果

方案2:利用Apollo缓存存储派生字段

通过Apollo Client的typePolicies配置,将转换后的值定义为缓存中的派生字段,让Apollo自动处理转换逻辑并缓存结果,所有查询该字段的组件都会共享缓存值。

首先修改查询,添加@client标记的本地派生字段:

query GetData {
  items {
    id
    rawField1
    rawField2
    combinedField @client # 本地派生字段
  }
}

然后配置Apollo Client的缓存策略:

import { ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: '/your-graphql-endpoint',
  cache: new InMemoryCache({
    typePolicies: {
      Item: {
        fields: {
          combinedField: {
            // 基于原始字段生成转换后的值,仅当原始字段变化时重新计算
            read(_, { readField }) {
              const raw1 = readField('rawField1');
              const raw2 = readField('rawField2');
              return `${raw1}_${raw2}`;
              // 替换为你的实际转换逻辑
            }
          }
        }
      }
    }
  })
});

此后任何组件查询combinedField时,Apollo都会直接从缓存读取转换后的值,无需重复执行转换。

方案3:通过React Context共享转换后的数据

如果需要共享数据的组件分散在不同层级,可以将查询与转换逻辑放在顶层Provider中,通过Context向下传递转换后的数据。

import { createContext, useContext, useQuery, useMemo } from 'react';
import { gql } from '@apollo/client';

const DataContext = createContext(null);

// 顶层Provider组件
export const DataProvider = ({ children }) => {
  const { data, loading, error } = useQuery(GET_DATA_QUERY);
  
  const transformedData = useMemo(() => {
    if (!data) return [];
    return transformRawData(data);
  }, [data]);

  return (
    <DataContext.Provider value={{ transformedData, loading, error }}>
      {children}
    </DataContext.Provider>
  );
};

// 自定义Hook用于获取Context数据
export const useSharedData = () => useContext(DataContext);

在App中包裹需要数据的组件:

import { DataProvider } from './DataProvider';

function App() {
  return (
    <DataProvider>
      <ComponentA />
      <ComponentB />
      {/* 其他需要数据的组件 */}
    </DataProvider>
  );
}

组件中使用:

const ComponentB = () => {
  const { transformedData, loading } = useSharedData();
  if (loading) return <div>Loading...</div>;
  // 渲染逻辑
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 01:52:02