Apollo 客户端:缓存更新后组件不呈现(反应变量)
Posted
技术标签:
【中文标题】Apollo 客户端:缓存更新后组件不呈现(反应变量)【英文标题】:Apollo Client: Component doesn't render after cache update (reactive variables) 【发布时间】:2021-04-27 08:22:20 【问题描述】:在这里看到了类似的问题,但我无法解决这些问题。我是功能组件和 Apollo 客户端的新手,在阅读 documentation 之后,创建了一个应该呈现项目列表的组件,然后(在添加时)更新缓存并从中读取,再次呈现组件。但是结果是不同的,我不明白为什么组件没有渲染。使用了 Apollo Client 和反应变量。
这是我的cache.js
:
import InMemoryCache, makeVar from "@apollo/client";
export const cache = new InMemoryCache(
dataIdFromObject: (object) => object.key,
typePolicies:
Query:
fields:
items:
read()
return itemsVar();
,
,
,
,
,
);
export const itemsVar = makeVar([]);
export default cache;
然后,我有以下组件:
import React, useState, Fragment from "react";
import useQuery, useReactiveVar, useMutation from "@apollo/client";
import GET_ALL_ACTIVE_ITEMS from "../../queries/Item";
import CREATE_ITEM from "../../mutations/Item";
import itemsVar from "../../cache";
//Components
import Item from "./Item";
const ItemContainer = () =>
// this gets the list of items upon component loading
const data = useQuery(GET_ALL_ACTIVE_ITEMS);
// Input to create the new Item
const [itemInput, setItemInput] = useState(
title: "",
);
const [createItem] = useMutation(CREATE_ITEM);
const onAddItemClick = (e) =>
e.preventDefault();
createItem(
variables:
itemInput: itemInput,
,
).then((res) =>
// Gets the result of the created Item and adds to cached
let resArray = [...res.data.itemInput];
itemsVar([...itemsVar().getAllActiveItems, resArray]);
);
;
const onChange = (e) =>
setItemInput( ...itemInput, [e.target.name]: e.target.value );
;
// Sets the cache reactive variable to the data from the backend
itemsVar(data);
const items = useReactiveVar(itemsVar);
return (
<div>
<div>
<div onClick=onAddItemClick className="primary-button">
Add item
</div>
<input
type="text"
name="title"
value=itemInput.title
onChange=onChange
/>
</div>
items && items.getAllActiveItems.length === 0 ? (
<p>No items</p>
) : (
<Fragment>
items &&
items.getAllActiveItems.map(( _id, title ) => (
<Item key=_id title=title />
))
</Fragment>
)
</div>
);
;
export default ItemContainer;
此组件在加载时正确呈现项目。现在,即使它创建了一个新项目,它也不会刷新组件(我假设缓存也没有更新,尽管不确定)。
获取所有项目查询:
import gql from "graphql-tag";
const GET_ALL_ACTIVE_ITEMS = gql`
query getAllActiveItems()
getAllActiveItems()
_id
title
`;
export default GET_ALL_ACTIVE_ITEMS;
创建项目查询,它创建一个项目并将其作为数组返回:
import gql from "graphql-tag";
const CREATE_ITEM = gql`
mutation createItem($itemInput: CreateItemInput!)
createItem(itemInput: $itemInput)
_id
title
`;
export default CREATE_ITEM;
你能帮我理解我在这里缺少什么吗?
【问题讨论】:
'突变后缓存更新' - 阅读文档 @xadm 与反应变量一样吗? 【参考方案1】:您没有指定是否要更新缓存或不在 useMutation 挂钩中。
useMutation 钩子也接受选项,如下所示:-
function useMutation<TData = any, TVariables = OperationVariables>(
mutation: DocumentNode,
options?: MutationHookOptions<TData, TVariables>,
): MutationTuple<TData, TVariables>
因此,如果您想在发生突变后更新缓存,请使用
const [createItem] = useMutation(CREATE_ITEM,update: updateCache);
const updateCache = (cache, data) =>
// Fetch from the cache
const existingItems = cache.readQuery(
query: GET_ALL_ACTIVE_ITEMS
);
// Add to the cache
const newItem = ....
cache.writeQuery(
query: GET_ALL_ACTIVE_ITEMS,
data: items: [newItem, ...existingItems]
);
;
【讨论】:
谢谢!在我的情况下 updateCache 将是反应变量本身? 你需要读写缓存,我已经更新了答案。 @Ruham以上是关于Apollo 客户端:缓存更新后组件不呈现(反应变量)的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 React HashRouter 和 Apollo 客户端渲染反应类组件?
如何在突变之前更新 apollo 缓存状态,以进行 Like、Upvote 等操作? [关闭]