В большинстве примеров в компоненте запроса используется 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 и сравнивать их на каждом рендере?
Есть ли более элегантный подход ко всему этому?





Вы когда-нибудь пробовали использовать 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)
@vemund рад, что это помогло!
Спасибо за это. У меня отлично сработало использование refetch ()!