Подтвердить что ты не робот

Как вы динамически контролируете реакцию инициации запроса 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);
4b9b3361

Ответ 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, чтобы проверить лучшие решения.