如何在React Apollo中实现输入DRY?复用GQL变量参数方案
React Apollo中复用GraphQL变量参数的方案
针对你遇到的「输入参数完全相同,但不同业务场景返回字段不同」的情况,完全可以通过外部抽离变量定义和复用调用参数两种方式来实现复用逻辑,具体方案如下:
1. 抽离共用变量定义(外部复用)
两个查询的变量声明部分完全重复,直接把这部分抽成字符串常量,拼接进gql模板即可,后续修改变量只需要维护一处:
// 抽离所有查询共用的变量定义 const COMMON_QUERY_VARS = ` $page: Int $a: String $b: Number $etc: EtcFilter `; // 第一个查询:复用变量定义 const REQUEST_1 = gql` query QueryA(${COMMON_QUERY_VARS}) { getData( limit: 24 page: $page a: $a b: $b etc: $etc ) { total result { id time location } } } `; // 第二个查询:同样复用变量定义 const REQUEST_2 = gql` query QueryA(${COMMON_QUERY_VARS}) { getData( limit: 24 page: $page a: $a b: $b etc: $etc ) { total result { postContent date coordinates id } } } `;
2. 复用查询参数值(调用时复用)
如果组件中调用这两个查询时传入的参数值完全一致,可以把参数对象抽成常量或封装成函数,避免重复编写参数:
静态参数复用
import { useQuery } from '@apollo/client'; function BusinessComponent() { // 抽离共用的参数值 const sharedQueryParams = { page: 1, a: 'default-value', b: 456, etc: { status: 'valid' } }; // 两个查询共用同一套参数 const { data: listData } = useQuery(REQUEST_1, { variables: sharedQueryParams }); const { data: detailData } = useQuery(REQUEST_2, { variables: sharedQueryParams }); // 业务逻辑处理... }
动态参数复用(比如依赖组件状态/Props)
function BusinessComponent({ currentPage }) { // 封装参数生成逻辑,动态计算参数 const getSharedParams = (page) => ({ page, a: props.filterValue, b: 123, etc: { type: 'business' } }); const currentParams = getSharedParams(currentPage); const { data: listData } = useQuery(REQUEST_1, { variables: currentParams }); const { data: detailData } = useQuery(REQUEST_2, { variables: currentParams }); }
3. 额外优化:用Fragment复用重叠返回字段
如果两个查询的返回字段有重叠(比如都包含id),可以用GraphQL的Fragment进一步减少重复代码:
// 定义共用字段片段 const BASE_RESULT_FRAGMENT = gql` fragment BaseResultFields on DataItem { id } `; const REQUEST_1 = gql` ${BASE_RESULT_FRAGMENT} query QueryA(${COMMON_QUERY_VARS}) { getData( limit: 24 page: $page a: $a b: $b etc: $etc ) { total result { ...BaseResultFields time location } } } `; const REQUEST_2 = gql` ${BASE_RESULT_FRAGMENT} query QueryA(${COMMON_QUERY_VARS}) { getData( limit: 24 page: $page a: $a b: $b etc: $etc ) { total result { ...BaseResultFields postContent date coordinates } } } `;
内容的提问来源于stack exchange,提问作者darkace
相关产品推荐
相关产品推荐

