Apollo useQuery 钩子不会使用 writeQuery() 方法从缓存中获取更新。没有看到错误
Posted
技术标签:
【中文标题】Apollo useQuery 钩子不会使用 writeQuery() 方法从缓存中获取更新。没有看到错误【英文标题】:Apollo useQuery hook doesn't get update from cache with writeQuery() method. No errors seen 【发布时间】:2020-02-01 00:12:57 【问题描述】:使用useMutation()
后,缓存会更新,但主页组件中的useQuery()
不会。
我尝试使用不同的fetchPolicy
。我可以在 Apollo 开发工具中看到新帖子,但需要更新页面才能看到更改
import FETCH_POSTS_QUERY from '../utils/graphql';
function Home()
const user = useContext(AuthContext);
const
loading,
data
= useQuery(FETCH_POSTS_QUERY,
fetchPolicy: 'cache-and-network',
);
...
import useMutation from '@apollo/react-hooks';
import useForm from '../utils/hooks';
import FETCH_POSTS_QUERY from '../utils/graphql';
function PostForm()
const values, onChange, onSubmit = useForm(createPostCallback,
body: ''
);
const [createPost, error ] = useMutation(CREATE_POST_MUTATION,
variables: values,
update(proxy, result)
const data = proxy.readQuery(
query: FETCH_POSTS_QUERY
);
data.getPosts.push(result.data.createPost);
proxy.writeQuery( query: FETCH_POSTS_QUERY, data );
values.body = '';
);
function createPostCallback()
createPost();
...
...
import InMemoryCache from 'apollo-cache-inmemory';
import createHttpLink from 'apollo-link-http';
import ApolloProvider from '@apollo/react-hooks';
import setContext from 'apollo-link-context';
const httpLink = createHttpLink(
uri: 'http://localhost:5000'
);
const authLink = setContext(() =>
const token = localStorage.getItem('jwttoken');
return
headers:
Authorization: token ? `Bearer $token` : ''
;
);
const client = new ApolloClient(
link: authLink.concat(httpLink),
cache: new InMemoryCache()
);
...
我希望在不更新页面的情况下看到新帖子。
【问题讨论】:
【参考方案1】:这段代码sn-p解决了你用PostForm写缓存时前端刷新的问题:
//在 Home.js 中使用这个:
const [posts, setPosts] = useState([]);
const user = useContext(AuthContext);
const loading, data = useQuery(FETCH_POSTS_QUERY);
useEffect(() =>
if (data)
setPosts(data.getPosts);
, [data]);
在 PostForm.js 中使用这个:
const [createPost, error ] = useMutation(CREATE_POST_MUTATION,
variables: values,
update(proxy, result)
const data = proxy.readQuery(
query: FETCH_POSTS_QUERY
);
const new_post = result.data.createPost;
proxy.writeQuery(
query: FETCH_POSTS_QUERY,
data: getPosts: [new_post, ...data.getPosts]
);
values.body = '';
);
这个解决方案不是我的主意,但一位代码英雄帮助我们:)
参考链接:https://gist.github.com/josuecatalan/5b8bf73e69d55683ccf237d5d02b5cef
原创内容: https://www.youtube.com/watch?v=F_SdB42DxdQ&list=PLMhAeHCz8S3_pgb-j51QnCEhXNj5oyl8n&index=6
【讨论】:
【参考方案2】:您在此处使用push
修改缓存数据:
data.getPosts.push(result.data.createPost);
然后原样返回
proxy.writeQuery( query: FETCH_POSTS_QUERY, data );
因为这是 javascript 并且对象是通过引用传递的,所以您返回的 data
与您收到的对象相同,所以 apollo 没有意识到它已经改变了。请尝试以下操作:
proxy.writeQuery( query: FETCH_POSTS_QUERY, data: ...data );
【讨论】:
现在它不会更新缓存,如果我喜欢这个javascript data.getPosts = [result.data.createPost, ...data.getPosts]
它就像以前一样工作
你还在修改同一个data
对象,试着按照我写的那样做并创建新的data
我遇到了同样的问题。有什么解决办法吗?
解决方案如我的帖子中所写。如果您无法修复它,那么您要么没有与 OP 相同的问题,要么您仍在重新使用缓存对象。每次都使用新对象更新缓存。【参考方案3】:
就我而言,后端团队只是重写了上传的图像文件并保留了旧名称。所以应用程序 UI 不想重新渲染。我浪费了几个小时来调试它。 所以不要忘记检查数据。
【讨论】:
以上是关于Apollo useQuery 钩子不会使用 writeQuery() 方法从缓存中获取更新。没有看到错误的主要内容,如果未能解决你的问题,请参考以下文章
Apollo 客户端没有读取使用 useQuery 钩子传入的变量
如何在 react/apollo 中调用条件 useQuery 钩子
@apollo/client 反应钩子 useQuery() 数据未定义
在@apollo/react-hooks 的 useQuery 钩子中忽略了跳过参数
如何使用 Apollo 客户端 useQuery 钩子防止不必要的重新获取?
如何将 React 钩子(useContext、useEffect)与 Apollo 反应钩子(useQuery)结合起来