阿波罗链接状态writeQuery不会更新缓存中的ROOT_QUERY,从而阻止了重新渲染组件

时间:2018-08-27 17:58:33

标签: reactjs graph oauth-2.0 react-apollo apollo-client

我正在通过自定义提供程序实现OAuth。 所以我有Auth组件在'componentDidMount:

client.mutate({
  mutation: CURRENT_USER_MUTATION,
  variables: {
    token: (response.data.token.value) || null,
   },
});

我的突变如下:

gql`
  mutation($token: String!) {
    CurrentUser(token: $token) @client
  }
`;

我有解析器:

defaults: {
  current_user: null,
},
resolvers: {
  Mutation: {
    CurrentUser: (_: any, { token }: { token: string }, { cache }: { cache: Object }): null => {
    const { user } = decodeJWT(token);

    cache.writeQuery({
      query: CURRENT_USER,
      data: {
        current_user: {
          __typename: 'user',
          id: user.id,
          name: user.name,
          level: user.level,
          email: user.email,
        },
      },
    });

    return cache.readQuery({ query: CURRENT_USER });
  },
},

然后发生了一些意外,当我查看chrome apollo调试器时,我可以清楚地看到:

chrome apollo dev tool

因此数据已经在Apollo缓存中,但是ROOT_QUERY的当前用户仍然为null。

当我尝试使用react-apollo Mutation组件时,也是如此:

<Mutation mutation={CURRENT_USER_MUTATION}>
  {(mutate: Function,): React.Node => {
    return (
      <button type="button" onClick={(): Function => mutate(({ variables: { token: '123' } }: Object))}>
        Do it
       </button>
     );
   }}
 </Mutation>

然后完美运行。

因此,在使用cache.writeQuery之后,其他组件/缓存看起来没有关于运行突变的通知。

感谢您的帮助:)

2 个答案:

答案 0 :(得分:1)

您的CurrentUser突变似乎是错误的。

这项应有的工作:

Mutation: {
  CurrentUser: (_: any, { token }: { token: string }, { cache }: { cache: Object 
}): null => {
  const { user } = decodeJWT(token);

  cache.writeQuery({
    query: CURRENT_USER,
    data: {
      current_user: {
        __typename: 'user',
        id: user.id,
        name: user.name,
        level: user.level,
        email: user.email,
      },
    },
  });

  return {
      current_user: {
        __typename: 'user',
        id: user.id,
        name: user.name,
        level: user.level,
        email: user.email,
      },
    }
},

答案 1 :(得分:0)

因此,最后,我发现问题出在不同的地方:P我的朋友Michał通过在此处制作我的代码的工作示例来建议我:https://codesandbox.io/s/l57k8v3o67

有几个结论: 1.仅当检测到用户交互时,组件才会重新获取/重新渲染。因此,例如单击,这就是带有可单击按钮的组件工作或向服务器发出某些请求的原因。

  1. 阿波罗(Apollo)有几个错误:)我有一个名为<PrivateRoute />的不同组件,基本上检查我们是否有current_user,然后重定向或渲染路由,这里是:https://gist.github.com/bslipek/b11caefba31599e30d498beaf8644cec并且该组件有一个错误来自ere的问题:https://github.com/apollographql/apollo-link-state/issues/236

因此,基本上,如果您将带有查询的组件呈现为本地状态,并且未设置fetchPolicy='cache-first',则Apollo会恢复为默认状态。