无法在呈现 nextjs apollo 应用程序的服务器中的组件中获取更新的缓存
Unable to get updated cache in component in a server rendered nextjs apollo app
我有一个使用 apollo 客户端状态的 nextjs apollo 服务器呈现的应用程序。
我面临的问题是,在应用程序加载时,即使本地状态已正确更新,header 组件中调用的本地状态 graphql 查询也不会 return 具有正确的最新状态数据,而不是 return 的初始状态。我无法弄清楚为什么会这样,是因为 apollo 客户端设置还是因为缓存 initialState。
该应用程序是使用 apollo 客户端的 nextjs 服务器呈现的应用程序。我已经广泛尝试调整 apollo 客户端设置以弄清楚状态重置的确切位置[我说重置是因为在更新状态后记录状态给了我正确的结果]。
apollo config是官方nextjs apollo的修改版example
// lib/apollo.js
...
const appCache = new InMemoryCache().restore(initialState);
const getState = (query) => appCache.readQuery({ query });
const writeState = (state) => appCache.writeData({ data: state });
initCache(appCache);
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: ApolloLink.from([consoleLink, errorLink, authLink, fileUploadLink]),
cache: appCache,
resolvers: StateResolvers(getState, writeState),
typeDefs,
defaults: {},
connectToDevTools: true,
});
...
// apollo/StateResolvers.js
export const GET_LOGIN_STATUS_QUERY = gql`
query {
loginStatus @client {
isLoggedIn
}
}
`;
export default (getState, writeState) => {
return {
Mutation: {
updateLoginStatus(_, data) {
const { loginStatus } = getState(GET_LOGIN_STATUS_QUERY);
const newState = {
...loginStatus,
loginStatus: {
...loginStatus,
...data,
},
};
writeState(newState);
const updatedData = getState(terminal); // getting correct updated state here
console.log('log updateLoginStatus:', updatedData);
return { ...data, __typename: 'loginStatus' };
},
},
};
};
// initCache.js
export default (appCache) =>
appCache.writeData({
data: {
loginStatus: {
isLoggedIn: false,
__typename: 'loginStatus',
},
},
});
Header 导入到 _app.js nextjs 文件中使用的 Layout 组件中
// header/index.js
...
const q = gql`
query {
loginStatus @client {
isLoggedIn
}
}
`;
const Header = (props) => {
const { loading, data, error } = useQuery(q); // not getting the updated state here
console.log('header query data:', loading, data, error);
return (
<div>header</div>
);
};
...
带有 result
的第二个日志是 checkLoggedIn
文件的输出,类似于 here
// server side terminal output
log updateLoginStatus: { loginStatus: { isLoggedIn: true, __typename: 'loginStatus' } }
result: { data: updateLoginStatus: { isLoggedIn: true, __typename: 'loginStatus' } } }
header query data: true undefined undefined {}
header query data: false { loginStatus: { isLoggedIn: false, __typename: 'loginStatus' } } undefined
header query data: false { loginStatus: { isLoggedIn: false, __typename: 'loginStatus' } } undefined
我的最终目标是在 header 中正确设置 isLoggedIn
标志,以便在登录和注销状态之间正确切换。
如果需要更多详细信息,请告诉我。任何帮助将不胜感激。
您似乎正在恢复初始状态
您想恢复服务器渲染状态。
例如:
假设你做到了
const state = apolloClient.extract();
return `
<script>
window.__APOLLO_STATE__ = ${JSON.stringify(state)};
</script>
`;
你想恢复这个状态
不是初始状态
我有一个使用 apollo 客户端状态的 nextjs apollo 服务器呈现的应用程序。 我面临的问题是,在应用程序加载时,即使本地状态已正确更新,header 组件中调用的本地状态 graphql 查询也不会 return 具有正确的最新状态数据,而不是 return 的初始状态。我无法弄清楚为什么会这样,是因为 apollo 客户端设置还是因为缓存 initialState。
该应用程序是使用 apollo 客户端的 nextjs 服务器呈现的应用程序。我已经广泛尝试调整 apollo 客户端设置以弄清楚状态重置的确切位置[我说重置是因为在更新状态后记录状态给了我正确的结果]。
apollo config是官方nextjs apollo的修改版example
// lib/apollo.js
...
const appCache = new InMemoryCache().restore(initialState);
const getState = (query) => appCache.readQuery({ query });
const writeState = (state) => appCache.writeData({ data: state });
initCache(appCache);
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: ApolloLink.from([consoleLink, errorLink, authLink, fileUploadLink]),
cache: appCache,
resolvers: StateResolvers(getState, writeState),
typeDefs,
defaults: {},
connectToDevTools: true,
});
...
// apollo/StateResolvers.js
export const GET_LOGIN_STATUS_QUERY = gql`
query {
loginStatus @client {
isLoggedIn
}
}
`;
export default (getState, writeState) => {
return {
Mutation: {
updateLoginStatus(_, data) {
const { loginStatus } = getState(GET_LOGIN_STATUS_QUERY);
const newState = {
...loginStatus,
loginStatus: {
...loginStatus,
...data,
},
};
writeState(newState);
const updatedData = getState(terminal); // getting correct updated state here
console.log('log updateLoginStatus:', updatedData);
return { ...data, __typename: 'loginStatus' };
},
},
};
};
// initCache.js
export default (appCache) =>
appCache.writeData({
data: {
loginStatus: {
isLoggedIn: false,
__typename: 'loginStatus',
},
},
});
Header 导入到 _app.js nextjs 文件中使用的 Layout 组件中
// header/index.js
...
const q = gql`
query {
loginStatus @client {
isLoggedIn
}
}
`;
const Header = (props) => {
const { loading, data, error } = useQuery(q); // not getting the updated state here
console.log('header query data:', loading, data, error);
return (
<div>header</div>
);
};
...
带有 result
的第二个日志是 checkLoggedIn
文件的输出,类似于 here
// server side terminal output
log updateLoginStatus: { loginStatus: { isLoggedIn: true, __typename: 'loginStatus' } }
result: { data: updateLoginStatus: { isLoggedIn: true, __typename: 'loginStatus' } } }
header query data: true undefined undefined {}
header query data: false { loginStatus: { isLoggedIn: false, __typename: 'loginStatus' } } undefined
header query data: false { loginStatus: { isLoggedIn: false, __typename: 'loginStatus' } } undefined
我的最终目标是在 header 中正确设置 isLoggedIn
标志,以便在登录和注销状态之间正确切换。
如果需要更多详细信息,请告诉我。任何帮助将不胜感激。
您似乎正在恢复初始状态
您想恢复服务器渲染状态。
例如:
假设你做到了
const state = apolloClient.extract();
return `
<script>
window.__APOLLO_STATE__ = ${JSON.stringify(state)};
</script>
`;
你想恢复这个状态
不是初始状态