无法在服务器呈现的nextjs apollo应用程序的组件中获取更新的缓存

时间:2019-10-30 18:16:41

标签: reactjs graphql apollo next.js apollo-client

我有一个使用apollo客户端状态的nextjs apollo服务器呈现的应用程序。 我面临的问题是,在应用程序加载时,即使正确更新了本地状态,在标头组件中调用的本地状态graphql查询也不会返回具有正确数据的最新状态,而是会返回初始状态。我无法弄清楚为什么会这样,这是由于apollo客户端设置还是由于缓存initialState。

该应用是使用apollo客户端的nextjs服务器呈现的应用。我已经广泛尝试调整apollo客户端设置以弄清楚重置状态到底在哪里[我说是重置,因为在更新状态后登录状态会为我提供正确的结果]。

apollo配置是官方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',
      },
    },
  });

标题已导入_app.js nextjs文件中使用的布局组件中

// 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

我的最终目标是在标题中获得正确设置的isLoggedIn标志,以便在登录状态和注销状态之间正确切换。

请让我知道是否需要更多详细信息。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

您似乎正在恢复初始状态

您要还原服务器的呈现状态。

例如:

让我们说你做了

const state = apolloClient.extract();

return `
<script>
  window.__APOLLO_STATE__ = ${JSON.stringify(state)};
</script>
`;

您要恢复此状态

不是初始状态