我正在使用nextjs和react-apollo(带钩子(Hook))。我正在尝试在突变后更新 Apollo 缓存中的用户对象(我不想重新获取)。发生的情况是,用户似乎在缓存中得到了很好的更新,但组件使用的用户对象没有得到更新。相关代码如下:
页面:
// pages/index.js
...
const Page = ({ user }) => {
return <MyPage user={user} />;
};
Page.getInitialProps = async (context) => {
const { apolloClient } = context;
const user = await apolloClient.query({ query: GetUser }).then(({ data: { user } }) => user);
return { user };
};
export default Page;
以及组件:
// components/MyPage.jsx
...
export default ({ user }) => {
const [toggleActive] = useMutation(ToggleActive, {
variables: { id: user.id },
update: proxy => {
const currentData = proxy.readQuery({ query: GetUser });
if (!currentData || !currentData.user) {
return;
}
console.log('user active in update:', currentData.user.isActive);
proxy.writeQuery({
query: GetUser,
data: {
...currentData,
user: {
...currentData.user,
isActive: !currentData.user.isActive
}
}
});
}
});
console.log('user active status:', user.isActive);
return <button onClick={toggleActive}>Toggle active</button>;
};
当我连续按下按钮时,更新功能中的控制台日志显示用户事件状态来回翻转,因此看来apollo缓存正在正确更新。但是,组件中的控制台日志始终显示相同的状态值。
我没有看到我正在执行的任何其他 apollo 缓存更新发生此问题,其中组件使用的数据对象是使用 useQuery Hook 在组件中获取的(即不是从 getInitialProps 中的查询获取的)。
请注意,我的 apollo ssr 设置与官方 nextjs 示例非常相似:https://github.com/zeit/next.js/tree/canary/examples/with-apollo
最佳答案
问题在于您正在调用客户端的query
方法。此方法只是向服务器发出请求并返回解析为响应的 Promise。因此,在渲染页面之前调用 getInitialProps
,调用 query
,Promise 解析,然后将生成的用户对象作为 prop 传递给页面组件。对缓存的更新不会触发再次运行 getInitialProps
(尽管我相信导航离开和导航回来应该),因此 user prop 在初始渲染后永远不会改变。
如果您想订阅缓存中的更改,则应使用 useQuery
Hook ,而不是使用 query
方法和 getInitialProps
。您还可以使用 Query
组件或 graphql
HOC 达到相同的效果,尽管这两个组件现在已被弃用,取而代之的是新的 hooks API。
export default () => {
const { data: { user } = {} } = useQuery(GetUser)
const [toggleActive] = useMutation(ToggleActive, { ... })
...
})
样板代码中使用的 getDataFromTree
方法(与设置初始缓存状态相结合)可确保运行使用 useQuery
Hook 为页面获取的任何查询在页面渲染之前,添加到缓存并用于实际的服务器端渲染。
useQuery
利用客户端的 watchQuery
方法创建一个可观察对象,该可观察对象会根据缓存的更改进行更新。因此,在组件最初在服务器端渲染后,客户端缓存的任何更改都将触发组件的重新渲染。
关于javascript - 下一个/React-Apollo : React props not hooked up to apollo cache when query comes from getInitialProps,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59331462/