ApolloConsumer и кеш - PullRequest
       6

ApolloConsumer и кеш

0 голосов
/ 21 сентября 2018

В настоящее время я использую React и Graphql с Apollo и Reaction-Apollo.Когда я хочу загрузить данные из Graphql, я обычно использую компонент изact-apollo, но если я хочу сделать вызов после события, такого как щелчок, насколько мне известно, мне нужно сделать это с помощьюApolloConsumer и client.query.

Но при этом, когда кэш обновляется или сбрасывается, все, что было загружено через ApolloConsumer, не обновляется.Вот пример:

import React, { Component } from "react";
import { render } from "react-dom";

import ApolloClient from "apollo-boost";
import { ApolloProvider, ApolloConsumer, Query } from "react-apollo";
import gql from "graphql-tag";

const client = new ApolloClient({
  uri: `https://m08pj5j9k9.lp.gql.zone/graphql`
});

class App extends Component {
  state = { client: [] };

  renderQuery = () => {
    return (
      <Query query={gql`{test01 {id, name}}`}>
        {({ loading, error, data }) => {
          if (loading) return "Loading...";
          if (error) return "Error";

          return (
            <ul>
              {data.test01.map(data => <li key={data.id}>{data.name}</li>)}
            </ul>
          );
        }}
      </Query>
    );
  };

  btnQueryClick = async client => {
    const data = await client.query({ query: gql`{test02 {id, name}}` });
    this.setState({ client: data.data.test02 });
  };

  render() {
    return (
      <ApolloProvider client={client}>
        <div>
          <h2>Query test</h2>
          {this.renderQuery()}

          <ApolloConsumer>
            {client => (
              <div>
                <h2>Client query test</h2>
                <button onClick={() => this.btnQueryClick(client)}>
                  Test!
                </button>
                <ul>
                  {this.state.client.map(data => (
                    <li key={data.id}>{data.name}</li>
                  ))}
                </ul>

                <h2>Store reset</h2>
                <button
                  onClick={() => {
                    client.resetStore();
                  }}
                >
                  {" "}
                  Reset!
                </button>
              </div>
            )}
          </ApolloConsumer>
        </div>
      </ApolloProvider>
    );
  }
}

render(<App />, document.getElementById("root"));

А вот ссылка, чтобы попробовать его вживую: https://codesandbox.io/s/5460952y3k

Во всех запросах я добавил случайное число, так что я знаю, если данные имеютизменилось.Как видите, данные в разделе «Проверка запроса» будут обновлены, если я нажму кнопку сброса, но не данные в разделе «Проверка запроса клиента».

Есть ли способ эмулироватьтакие же обновления с ApolloConsumer?

Спасибо

Ответы [ 2 ]

0 голосов
/ 22 сентября 2018

Вы не можете ожидать автоматических обновлений запущенных вручную запросов.

Даже повторно обработанные (если это произошло, но это не так) потребитель не будет 'refire' событие, то нетЗапрошено, нет состояния (и просмотра).

Запрос не создает какой-либо наблюдаемой - вы, вероятно, ищете смешивание ручных запросов с подписками.

Зачем вам нужно смотретьдля других обновлений кэша?

Попробуйте использовать «традиционные» HOC от Apollo и составьте - ИМХО гораздо более читабельный, управляемый и подходящий для более сложных sceanrios.

0 голосов
/ 22 сентября 2018

Да, я думаю, что для вашего конкретного случая использования client.query, вероятно, не подходит.Вот кодовая ручка, которая, как мне кажется, вам нужна: https://codesandbox.io/s/yw779qx8qv

И источник:

import React, { Component } from "react";
import { render } from "react-dom";

import ApolloClient from "apollo-boost";
import { ApolloProvider, ApolloConsumer, Query } from "react-apollo";
import gql from "graphql-tag";

const client = new ApolloClient({
  uri: `https://m08pj5j9k9.lp.gql.zone/graphql`
});

class App extends Component {
  state = { showOtherQuery: false };

  renderQuery = () => {
    return (
      <Query query={gql`{test01 {id, name}}`}>
        {({ loading, error, data }) => {
          if (loading) return "Loading...";
          if (error) return "Error";

          return (
            <ul>
              {data.test01.map(data => <li key={data.id}>{data.name}</li>)}
            </ul>
          );
        }}
      </Query>
    );
  };

  renderOtherQuery() {
    return (
      <Query query={gql`{test02 {id, name}}`}>
        {({ loading, error, data }) => {
          if (loading) return "Loading...";
          if (error) return "Error";

          return (
            <ul>
              {data.test02.map(data => <li key={data.id}>{data.name}</li>)}
            </ul>
          );
        }}
      </Query>
    );
  }

  render() {
    return (
      <ApolloProvider client={client}>
        <div>
          <h2>Query test</h2>
          {this.renderQuery()}

          <div>
            <h2>Client query test</h2>
            <button onClick={() => this.setState({ showOtherQuery: true })}>
              Test!
            </button>
            {this.state.showOtherQuery && this.renderOtherQuery()}

            <h2>Store reset</h2>
            <button
              onClick={() => {
                client.resetStore();
              }}
            >
              {" "}
              Reset!
            </button>
          </div>
        </div>
      </ApolloProvider>
    );
  }
}

render(<App />, document.getElementById("root"));

По сути, кнопка больше не выдает запрос вручную с помощью клиента.query, но вместо этого устанавливает логическое значение, которое отображает дополнительный компонент Query, который затем будет обновляться так, как вы ожидаете при сбросе хранилища.

Альтернативой является ручной вызов client.query и повторная установка состояния (что в основном и делает компонент Query) при нажатии кнопки сброса.

...