React中基于locale动态管理GraphQL查询的代码冗余问题如何解决
解决方案
1. 核心优化思路:将locale作为GraphQL查询变量传递
你原来的实现是直接把locale通过模板字符串硬编码到查询语句里,才导致查询无法抽离复用。改用GraphQL原生的变量机制传递locale,就可以把查询语句完全抽离到外部公共文件。
2. 具体实现步骤
第一步:抽离公共查询到独立文件
新建src/graphql/queries.js文件,写入以下内容:
import { gql } from '@apollo/client' // 替换为你项目里实际的gql导出包 // 抽离后的独立查询,完全静态,不需要动态拼接参数 export const GET_ITEMS = gql` query getItems($id: String!, $locale: String!) { Items(id: $id) { id notes nameTranslate(language: $locale) defaultClass { nameTranslate(language: $locale) } } } `
如果有大量同类带翻译字段的查询,还可以用GraphQL片段进一步复用翻译部分的代码,减少重复编写:
// 提前定义可复用的翻译片段,Node替换为你实际的接口返回类型名 const NAME_TRANSLATE_FRAGMENT = gql` fragment NameTranslate on Node { nameTranslate(language: $locale) } ` // 其他查询都可以直接引用片段 export const GET_ITEMS = gql` query getItems($id: String!, $locale: String!) { Items(id: $id) { id notes ...NameTranslate defaultClass { ...NameTranslate } } } ${NAME_TRANSLATE_FRAGMENT} `
第二步:组件内使用抽离的查询
直接引入公共查询,把当前locale作为变量传给查询接口即可,不管你用的是Apollo Client的useQuery钩子,还是自定义的fetch方法,都支持传变量:
import { useIntl } from 'react-intl' import { useQuery } from '@apollo/client' import { GET_ITEMS } from '@/graphql/queries' export const App = () => { const { locale } = useIntl() // 直接把locale作为变量传递,locale变化时会自动触发重新查询 const { data, loading } = useQuery(GET_ITEMS, { variables: { id: '你的业务id', locale: locale } }) // 其他业务逻辑 }
额外优势
这种写法除了解决查询复用的问题,还能保留GraphQL的缓存能力:不同locale的查询结果会被独立缓存,相同参数重复查询时不需要重新请求接口,性能远优于原来动态拼接查询字符串的实现。
内容的提问来源于stack exchange,提问作者WildThing
相关产品推荐
相关产品推荐

