如何用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)**来管理简单本地状态,更简洁:
- 在
apollos.js中定义响应式变量:
import { makeVar } from '@apollo/client'; // 定义模态框状态变量,初始值为false export const modalIsOpenVar = makeVar(false);
- 在组件中直接使用:
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
相关产品推荐
相关产品推荐

