当更新缓存时,React Apollo不更新组件

时间:2019-07-14 20:35:20

标签: javascript reactjs graphql react-apollo

在我的应用程序中,我有多个Query组件,在它们关联的Mutation组件对服务器上的数据进行更改之后,应该对其进行更新。不幸的是,这些似乎不起作用。这些对之一的示例:

class PlayerNames extends React.Component{
  render(){
    return (
      <Query
        query={PLAYER_NAMES}
        variables={{
          serverID: this.props.serverID,
          guid: this.props.guid
        }}
        onError={() => {}}
      >
        {({ loading, error, data }) => {
          if(loading) return <Loader />;
          if(error) return <Error />;

          if(data.server.player === null) return <NotFound/>;

          return (
            <Component
              serverID={this.props.serverID}
              guid={this.props.guid}
              names={data.server.player.playerNames}
            />
          );
        }}
      </Query>
    );
  }
}

此组件显示播放器名称列表。每个玩家名称都有一个显示更多信息的模式和一个擦除玩家名称的按钮。此按钮由React Apollo的Mutation组件提供动力:

class WipeName extends React.Component{
  render(){
    return (
      <Mutation
        mutation={WIPE_PLAYER_NAME}
        update={(cache, { data: { wipePlayerName }}) => {
          let { server } = cache.readQuery({
            query: PLAYER_NAMES,
            variables: {
              serverID: this.props.serverID,
              guid: this.props.guid
            }
          });

          server.player.playerNames = server.player.playerNames.filter(
            name => name._id !== wipePlayerName._id
          );

          cache.writeQuery({
            query: PLAYER_NAMES,
            variables: {
              serverID: this.props.serverID,
              guid: this.props.guid
            },
            data: { server }
          });
        }}
        onError={() => {}}
      >
        {(wipePlayerName, { loading, error }) => (
          <>
            {
              error &&
              <ErrorModal errors={error.graphQLErrors} />

            }
            <Button
              color="default"
              className="btn-white"
              onClick={() => {
                wipePlayerName({
                  variables: {
                    serverID: this.props.serverID,
                    name: this.props.name
                  }
                });
                if(this.props.onClick) this.props.onClick();
              }}
            >
              {
                (loading) ?
                  (
                    <>
                      <i className="fas fa-circle-notch fa-spin" />{" "}
                      Loading...
                    </>
                  ) : (
                    <>Wipe Player Name</>
                  )
              }
            </Button>
          </>
        )}
      </Mutation>
    );
  }
}

如您所见,我已经尝试update prop来更新我的缓存。我已经确认,通过在readCache之后重新调用writeCache方法并记录结果 (通过导航到另一个页面并返回强制重新渲染而不通过向服务器发送新查询。使用console.log(),我已经可以确认问题似乎是在更新缓存后,没有强制更新组件。我已经筋疲力尽了,请多多帮助。预先感谢。

其他代码段:

const client = new ApolloClient({
  request: async (operation) => {
    operation.setContext({ headers: { JWT: Auth.jwtToken } });
  },
  cache: new InMemoryCache({
    dataIdFromObject: obj => {
      switch (obj.__typename) {
        case 'serverconfigfile':
          return obj.name;
        case 'item':
          return obj.id;
        default:
          return obj._id;
      }
    }
  })
})

...

  <ApolloProvider client={client}>
    <BrowserRouter>
      <Switch>
        {indexRoutes}
        {adminRoutes}
      </Switch>
    </BrowserRouter>
  </ApolloProvider>

突变:

export default gql`
  mutation WipePlayerName($serverID: Int!, $name: String!){
    wipePlayerName(serverID: $serverID, name: $name) {
      _id
    }
  }
`;

查询:

export default gql`
  query PlayerNames($serverID: Int!, $guid: String!){
    server(id: $serverID){
      _id

      player(guid: $guid){
        _id

        playerNames {
          _id
          name
          lastSeen
        }
      }
    }
  }
`;

0 个答案:

没有答案