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

如何用apollo-link-state正确创建默认值?Redux转Apollo遇缓存问题

在Apollo缓存中存储模态框显示状态的实现方案

嘿,我来帮你理清楚怎么用Apollo的本地状态管理来存储模态框的显示状态!结合你提到的apollo-link-state和apollo-cache-inmemory,咱们一步步拆解实现逻辑:

1. 配置Apollo Client的本地状态

首先需要在你的apollos.js中定义本地状态的GraphQL Schema、初始值和处理读写的Resolvers,再把它们整合到Apollo Client的配置里:

// apollos.js
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloLink } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import { withClientState } from 'apollo-link-state';
import gql from 'graphql-tag';

// 1. 定义本地状态的GraphQL Schema
const typeDefs = `
  type ModalState {
    isOpen: Boolean!
  }

  type Query {
    modalState: ModalState!
  }

  type Mutation {
    setModalState(isOpen: Boolean!): ModalState!
  }
`;

// 2. 设置初始状态(默认模态框关闭)
const defaults = {
  modalState: {
    __typename: 'ModalState',
    isOpen: false
  }
};

// 3. 定义Resolvers,处理本地状态的查询与更新
const resolvers = {
  Query: {
    modalState: (_, __, { cache }) => {
      // 从缓存读取模态框状态
      const data = cache.readQuery({ query: GET_MODAL_STATE });
      return data.modalState;
    }
  },
  Mutation: {
    setModalState: (_, { isOpen }, { cache }) => {
      // 构造新状态并写入缓存
      const newState = {
        __typename: 'ModalState',
        isOpen
      };
      cache.writeQuery({
        query: GET_MODAL_STATE,
        data: { modalState: newState }
      });
      return newState;
    }
  }
};

// 4. 定义查询模态框状态的GraphQL语句(@client标记这是本地查询)
export const GET_MODAL_STATE = gql`
  query GetModalState {
    modalState @client {
      isOpen
    }
  }
`;

// 5. 创建本地状态Link
const stateLink = withClientState({
  cache: new InMemoryCache(),
  typeDefs,
  defaults,
  resolvers
});

// 6. 创建远程请求Link(如果你的应用有远程GraphQL接口)
const httpLink = new HttpLink({
  uri: '你的远程GraphQL地址'
});

// 7. 组合Links并创建Apollo Client实例
const client = new ApolloClient({
  link: ApolloLink.from([stateLink, httpLink]),
  cache: new InMemoryCache()
});

export default client;

2. 在组件中查询模态框状态

用useQuery钩子获取缓存中的模态框状态,控制组件渲染:

import { useQuery } from '@apollo/react-hooks';
import { GET_MODAL_STATE } from './apollos';

function MyModal() {
  const { data } = useQuery(GET_MODAL_STATE);
  const isModalOpen = data.modalState.isOpen;

  return (
    isModalOpen && (
      <div className="modal">
        {/* 模态框内容 */}
        <h2>这是模态框</h2>
      </div>
    )
  );
}

3. 更新模态框状态

用useMutation钩子触发状态更新,同步到缓存:

import { useMutation } from '@apollo/react-hooks';
import gql from 'graphql-tag';
import { GET_MODAL_STATE } from './apollos';

// 定义更新模态框状态的Mutation
const SET_MODAL_STATE = gql`
  mutation SetModalState($isOpen: Boolean!) {
    setModalState(isOpen: $isOpen) @client {
      isOpen
    }
  }
`;

function ModalToggleButton() {
  const [setModalState] = useMutation(SET_MODAL_STATE, {
    // 手动更新缓存,确保查询能立即获取最新状态
    update(cache, { data: { setModalState } }) {
      cache.writeQuery({
        query: GET_MODAL_STATE,
        data: { modalState: setModalState }
      });
    }
  });

  return (
    <>
      <button onClick={() => setModalState({ variables: { isOpen: true } })}>
        打开模态框
      </button>
      <button onClick={() => setModalState({ variables: { isOpen: false } })}>
        关闭模态框
      </button>
    </>
  );
}

补充:现代Apollo Client的轻量化方案

如果你的项目用的是Apollo Client 3.x及以上版本,apollo-link-state已经被官方废弃,推荐用**响应式变量(Reactive Variables)**来管理简单本地状态,更简洁:

  1. 在apollos.js中定义响应式变量:
import { makeVar } from '@apollo/client';

// 定义模态框状态变量,初始值为false
export const modalIsOpenVar = makeVar(false);
  1. 在组件中直接使用:
import { useReactiveVar } from '@apollo/client';
import { modalIsOpenVar } from './apollos';

function MyModal() {
  const isModalOpen = useReactiveVar(modalIsOpenVar);
  return isModalOpen && <div className="modal">...</div>;
}

function ModalToggleButton() {
  return (
    <>
      <button onClick={() => modalIsOpenVar(true)}>打开模态框</button>
      <button onClick={() => modalIsOpenVar(false)}>关闭模态框</button>
    </>
  );
}

核心逻辑总结

Apollo本地状态管理的本质是把本地数据存在InMemoryCache中,通过GraphQL语法(或响应式变量)实现读写。apollo-link-state的作用是打通本地Schema、Resolvers和缓存,让你用操作远程GraphQL的方式管理本地状态;而响应式变量则是轻量化方案,适合简单状态的快速实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:28:37