Как я могу refetch () мой запрос только при поступлении новых данных подписки?

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

У меня есть данные временных рядов, добавляемые в базу данных, запускающую подписку 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.info("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.info("queryData: ", queryData.getHistogram.columns);
          return (<p>{queryData.getHistogram.columns[0].binWidth}</p>);
        }
        return null
      }}
    </Subscription>
  )
  }
</Query>

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

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
853
1

Ответы 1

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

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

Вот фрагмент кода для вашего случая. (Я использовал hoc graphql из response-apollo, чтобы помочь внедрить перерисовать и 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)

Спасибо за это. У меня отлично сработало использование refetch ()!

vemund 07.05.2019 15:29

@vemund рад, что это помогло!

wei 07.05.2019 18:20

Другие вопросы по теме