Как я могу перезапустить () мой запрос только при получении новых данных подписки? - PullRequest
0 голосов
/ 03 мая 2018

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

У меня есть данные временных рядов, которые добавляются в базу данных, вызывая подписку onChangedWeatherIntervals, которая возвращает сводную информацию о новых данных временных рядов. Если информация о новом временном ряду соответствует фильтрам клиента React, он должен запросить обновленный запрос гистограммы getHistogram.

Мой тестовый код:

<Query
  query={gql`
    {
      getHistogram (deviceID:"ARMS-NVM-P16", startTimestamp:1525201056) {
        columns {
          binWidth
          binHeight
          binCenter
        }
      }
     }
  `}
>
  {({
      loading: queryLoading,
      error: queryError,
      data: queryData,
      refetch
    }) => (
    <Subscription
      subscription={gql`
        subscription onChangedWeatherIntervals {
          onChangedWeatherIntervals {
            changedItems {
              deviceID
              timestamp
              siteKey
            }
          }
        }
      `}>
      {({
          data: subscriptionData,
          loading: subscriptionLoading,
          error: subscriptionError
        }) => {
        if (subscriptionData && !subscriptionLoading) {
          console.log("subscriptionData: ", subscriptionData);
          //TODO: Add code to inspect subscriptionData & determine if we refetch
          //refetch() //Uncommenting causes refetch loop after first server push
        }
        if (queryData && !queryLoading) {
          console.log("queryData: ", queryData.getHistogram.columns);
          return (<p>{queryData.getHistogram.columns[0].binWidth}</p>);
        }
        return null
      }}
    </Subscription>
  )
  }
</Query>

Поскольку subscriptionLoading - это true только до первого нажатия сервера после монтирования, я не уверен, что это лучший способ отличить повторные рендеры от новых subscriptionData. Должен ли я хранить subscriptionData в state.subscriptionData и сравнивать два на каждом рендере?

Есть ли более элегантный подход ко всему этому?

1 Ответ

0 голосов
/ 23 июля 2018

Вы когда-нибудь пытались использовать subscribeToMore в своем запросе? Вы, вероятно, можете вызвать refetch в его команде updateQuery.

ОБНОВЛЕНИЕ : Я столкнулся с той же проблемой в своем приложении и нашел способ ее решить. Не стесняйтесь проверить это здесь . По сути, вам следует избегать использования логики подписки в методе render , который вызовет бесконечную проблему с повторным рендерингом / повторным рендерингом. Решение состоит в том, чтобы убрать логику из метода рендеринга и поместить ее в метод жизненного цикла , как componentDidMount. Таким образом, подписка больше не будет вызываться после запуска повторного поиска.

Вот фрагмент кода для вашего случая. (Я использовал hoc graphql из'act-apollo ', чтобы помочь вводить запросы refetch и subscribeToMore в реквизиты).

import { graphql } from 'react-apollo';

class YourComponent extends React.Component {
  componentDidMount() {
    const { data: { refetch, subscribeToMore }} = this.props;

    this.unsubscribe = subscribeToMore({
      document: <ON_CHANGED_WEATHER_INTERVALS>,
      updateQuery: (prev) => {
        refetch();
        return prev;
      },     
    });
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    const { data: {queryData, loading, error } } = this.props;

    if (loading || error) return null;

    return <p>{queryData.getHistogram.columns[0].binWidth}</p>
  }
}

export default graphql(GET_HISTOGRAM, {
  options: {
    variables: {
      deviceID: 'ARMS-NVM-P16',
      startTimestamp:1525201056,
    },
  },
})(YourComponent)
...