在这里看到了类似的问题,但无法解决这些问题。我是功能组件和 Apollo Client 的新手,在阅读 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;
你能帮我理解我在这里遗漏了什么吗?
答案 0 :(得分:2)
您没有在 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]}
});
};