Как вы динамически контролируете реакцию инициации запроса apollo-client?
Реактивный компонент, обернутый с помощью apollo-client, автоматически инициирует вызов сервера для данных.
Я хотел бы отключить запрос данных только на конкретном входе пользователя.
Вы можете передать опцию пропуска в параметрах запроса - но это означает, что функция refetch() не предоставляется в качестве опоры для компонента; и кажется, что значение пропусков динамически не оценивается при обновлении prop.
Мое использование - это компонент карты. Я хочу, чтобы данные для маркеров были загружены, когда пользователь нажимает кнопку, но не на первоначальное изменение компонентов или изменение местоположения.
Пример кода ниже:
// GraphQL wrapping
Explore = graphql(RoutesWithinQuery, {
options: ({ displayedMapRegion }) => ({
variables: {
scope: 'WITHIN',
targetRegion: mapRegionToGeoRegionInputType(displayedMapRegion)
},
skip: ({ targetResource, searchIsAllowedForMapArea }) => {
const skip = Boolean(!searchIsAllowedForMapArea || targetResource != 'ROUTE');
return skip;
},
}),
props: ({ ownProps, data: { loading, viewer, refetch }}) => ({
routes: viewer && viewer.routes ? viewer.routes : [],
refetch,
loading
})
})(Explore);
Ответы
Ответ 1
Чтобы включить HoC на основе условия, повлиявшего на изменение реквизита, вы можете использовать branch
от recompose
.
branch(
test: (props: Object) => boolean,
left: HigherOrderComponent,
right: ?HigherOrderComponent
): HigherOrderComponent
check: https://github.com/acdlite/recompose/blob/master/docs/API.md#branch
Для этого конкретного примера будет выглядеть примерно так:
const enhance = compose(
branch(
// evaluate condition
({ targetResource, searchIsAllowedForMapArea }) =>
Boolean(!searchIsAllowedForMapArea || targetResource != 'ROUTE'),
// HoC if condition is true
graphql(RoutesWithinQuery, {
options: ({ displayedMapRegion }) => ({
variables: {
scope: 'WITHIN',
targetRegion: mapRegionToGeoRegionInputType(displayedMapRegion)
},
}),
props: ({ ownProps, data: { loading, viewer, refetch } }) => ({
routes: viewer && viewer.routes ? viewer.routes : [],
refetch,
loading
})
})
)
);
Explore = enhance(Explore);
Ответ 2
У меня есть аналогичный вариант использования, я хотел загрузить данные только тогда, когда пользователь нажал.
Я не пробовал предложение withQuery, данное карандашом выше. Но я видел такое же предложение в другом месте. Я попробую, но в то же время это то, как я получил работу основанный на обсуждении github:
./loadQuery.js
Примечание. Я использую директиву пропуска:
const LOAD = `
query Load($ids:[String], $skip: Boolean = false) {
things(ids: $ids) @skip(if: $skip) {
title
}
`
LoadMoreButtonWithQuery.js
Здесь я использую функцию withState
более высокого порядка, чтобы добавить флаг и установщик флагов для управления skip
:
import { graphql, compose } from 'react-apollo';
import { withState } from 'recompose';
import LoadMoreButton from './LoadMoreButton';
import LOAD from './loadQuery';
export default compose(
withState('isSkipRequest', 'setSkipRequest', true),
graphql(
gql(LOAD),
{
name: 'handleLoad',
options: ({ids, isSkipRequest}) => ({
variables: {
ids,
skip: isSkipRequest
},
})
}
),
)(Button);
./LoadMoreButton.js
Здесь мне нужно вручную "перевернуть" добавленный флаг с помощью withState
:
export default props => (
<Button onClick={
() => {
props.setSkipRequest(false); // setter added by withState
props.handleLoad.refetch();
}
}>+</Button>
);
Откровенно говоря, я немного недоволен этим, так как он вводит новый набор проводов (составленный с помощью "withState" ). Его также не испытали на битвах - я только что начал работать, и я пришел в StackOverflow, чтобы проверить лучшие решения.