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

Apollo GraphQL:如何从缓存获取Mutation写入的数据?

嘿,针对你在React Native应用里处理GraphQL Mutation返回数据缓存的需求,我整理了两种实用方案,你可以根据自己的技术栈来选~


方案1:用Apollo Client管理缓存(推荐)

如果你的项目用了Apollo Client这类专业GraphQL客户端,它自带缓存管理能力,只需要做一点配置就能让Mutation返回的用户信息自动进入缓存,方便后续根查询读取。

  • 第一步:确保Mutation返回完整的用户字段
    先让你的登录/认证Mutation返回需要的用户信息,比如:

    mutation Login($credentials: CredentialsInput!) {
      login(credentials: $credentials) {
        token
        user {
          id
          name
          email
          avatar
        }
      }
    }
    
  • 第二步:在Mutation中手动更新缓存
    Apollo Client默认不会自动把Mutation结果同步到查询缓存里,所以需要用update函数把返回的用户数据写入缓存,和你的根查询结构匹配:

    import { gql, useMutation } from '@apollo/client';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    
    // 定义登录Mutation和用户查询
    const LOGIN_MUTATION = gql`
      mutation Login($credentials: CredentialsInput!) {
        login(credentials: $credentials) {
          token
          user {
            id
            name
            email
          }
        }
      }
    `;
    const GET_USER_QUERY = gql`
      query GetCurrentUser {
        user {
          id
          name
          email
        }
      }
    `;
    
    function LoginScreen() {
      const [login] = useMutation(LOGIN_MUTATION, {
        update(cache, { data: { login } }) {
          // 将返回的user数据写入缓存,匹配根查询的结构
          cache.writeQuery({
            query: GET_USER_QUERY,
            data: { user: login.user },
          });
          // 同时把token存入AsyncStorage
          AsyncStorage.setItem('authToken', login.token);
        },
      });
    
      const handleLogin = async (email, password) => {
        try {
          await login({ variables: { credentials: { email, password } } });
          // 登录成功后跳转首页等逻辑
        } catch (err) {
          console.error('登录失败:', err);
        }
      };
    
      // 登录UI代码...
    }
    
  • 第三步:从缓存读取用户信息
    之后用useQuery调用根查询时,Apollo会直接从缓存取数据,不用重复发请求:

    import { useQuery } from '@apollo/client';
    import { ActivityIndicator, View, Text } from 'react-native';
    
    function HomeScreen() {
      const { data, loading } = useQuery(GET_USER_QUERY);
    
      if (loading) return <ActivityIndicator />;
    
      return (
        <View>
          <Text>欢迎回来,{data.user.name}!</Text>
        </View>
      );
    }
    

另外,记得初始化Apollo Client时把AsyncStorage里的token加到请求头,保证后续请求带认证信息:

import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import AsyncStorage from '@react-native-async-storage/async-storage';

const httpLink = createHttpLink({
  uri: '你的GraphQL服务端地址',
});

const authLink = setContext(async (_, { headers }) => {
  const token = await AsyncStorage.getItem('authToken');
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : '',
    },
  };
});

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),
});

方案2:手动处理HTTP请求与缓存

如果没用到GraphQL客户端,自己用fetch或axios发请求的话,就需要手动管理缓存,比如用AsyncStorage或者全局状态(Context/Redux)。

  • 第一步:发送Mutation并保存数据
    发送POST请求到GraphQL端点,拿到token和用户信息后,分别存入AsyncStorage:

    import AsyncStorage from '@react-native-async-storage/async-storage';
    import axios from 'axios';
    
    const handleLogin = async (email, password) => {
      try {
        const response = await axios.post('你的GraphQL服务端地址', {
          query: `
            mutation Login($credentials: CredentialsInput!) {
              login(credentials: $credentials) {
                token
                user {
                  id
                  name
                  email
                }
              }
            }
          `,
          variables: { credentials: { email, password } },
        });
    
        const { token, user } = response.data.data.login;
        // 存token
        await AsyncStorage.setItem('authToken', token);
        // 存用户信息到缓存
        await AsyncStorage.setItem('currentUser', JSON.stringify(user));
      } catch (err) {
        console.error('登录失败:', err);
      }
    };
    
  • 第二步:从缓存读取用户信息
    用Context来管理用户状态会更方便,避免重复读取AsyncStorage:

    import { createContext, useContext, useEffect, useState } from 'react';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    import { ActivityIndicator, View, Text } from 'react-native';
    
    const UserContext = createContext();
    
    export function UserProvider({ children }) {
      const [user, setUser] = useState(null);
    
      useEffect(() => {
        const loadStoredUser = async () => {
          const storedUser = await AsyncStorage.getItem('currentUser');
          if (storedUser) setUser(JSON.parse(storedUser));
        };
        loadStoredUser();
      }, []);
    
      return (
        <UserContext.Provider value={{ user, setUser }}>
          {children}
        </UserContext.Provider>
      );
    }
    
    // 在组件中使用
    function HomeScreen() {
      const { user } = useContext(UserContext);
    
      if (!user) return <ActivityIndicator />;
    
      return (
        <View>
          <Text>欢迎回来,{user.name}!</Text>
        </View>
      );
    }
    

小提醒

不管用哪种方案,当用户修改个人信息时,记得同步更新缓存/状态,保证数据一致性哦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:36:27