如何修改Gatsby GraphQL返回数据且不改动原始缓存数据?
Gatsby 对 GraphQL 返回数据的处理逻辑
Gatsby 客户端侧的 GraphQL 查询结果会被存储在全局公共缓存中,所有页面共享同一份缓存数据引用。你直接修改查询返回的 data 对象属性时,本质是修改了缓存中的原始数据,下一次访问同页面读取缓存时,拿到的就是被修改后的数据,自然会出现属性不存在的报错。
你之前用 map 没有生效的原因是只拷贝了数组本身,数组中存储的 car 对象依然是原始缓存对象的引用,修改 car 的属性依然会污染缓存。
解决方案
方案1:页面内深拷贝数据后处理
在页面中处理时,先拷贝每个节点对象,再修改属性,避免操作原始引用:
const IndexPage = ({ data: { allWpMasina } }) => { // 拷贝每个car对象,重写目标属性,完全不触碰原始缓存数据 const cars = allWpMasina.nodes.map(car => ({ ...car, // 可选链兼容无属性的极端场景,避免报错 atrumkarbas: car.atrumkarbas?.nodes?.[0]?.name ?? '' })) // 后续业务代码直接使用处理后的cars数组即可 }
方案2:构建阶段自定义字段(更推荐)
直接在 Gatsby 构建阶段通过自定义 Schema 和解析器,把预处理逻辑放在服务端,客户端直接查询处理好的字段,从根源避免缓存污染问题:
- 在项目根目录的
gatsby-node.js中添加如下配置:
exports.createSchemaCustomization = ({ actions }) => { const { createTypes } = actions // 自定义新增字段 createTypes(` type WpMasina implements Node { atrumkarbasName: String! } `) } exports.createResolvers = ({ createResolvers }) => { createResolvers({ WpMasina: { atrumkarbasName: { resolve(source) { // 构建阶段就把属性处理好 return source.atrumkarbas?.nodes?.[0]?.name ?? '' } } } }) }
- 修改页面的 GraphQL 查询语句,直接查询新字段:
export const query = graphql` query { allWpMasina(limit: 6) { nodes { id atrumkarbasName } } } `;
之后页面中可以直接通过 car.atrumkarbasName 拿到目标值,不需要额外处理,也不会出现缓存相关问题。
内容的提问来源于stack exchange,提问作者HenrijsS
相关产品推荐
相关产品推荐

