Есть ли недостатки использования синглетов useLazyQuery? - PullRequest
0 голосов
/ 02 мая 2020

Скажите, что я делаю что-то вроде этого:

import React, { useContext } from 'react';
import { useLazyQuery } from '@apollo/react-hooks';
import type { DocumentNode } from 'graphql';
import { stringifyGqlTag } from '...'; // some path, my own method

export const GqlContext = React.createContext<GqlContextT>({});

export const useGqlLazyQuery = (gqlTag: DocumentNode) => {
  return useContext(GqlContext)[stringifyGqlTag(gqlTag)];
};

export const GqlContextProvider = ({ children }: { children: React$Node }) => {
  const value = {
    [FOO_GQL_STRING]: useLazyQuery(FOO_GQL),
    [BAR_GQL_STRING]: useLazyQuery(BAR_GQL),
    // ...
    // This could be a lot since we're going to have all the `useLazyQuery` within the app here. 
    // Could easily reach 50+, really depends on how big the app is...
  };
  return <GqlContext.Provider value={value}>{children}</GqlContext.Provider>;
};

--------------------------------------------

// In some other file, we have the gql stuff
import gql from 'graphql-tag';
import { stringifyGqlTag } from '...'; // some path, my own method

export const FOO_GQL = gql`...`;
export const FOO_GQL_STRING = stringifyGqlTag(FOO_GQL);
...

Использование его в компонентах:

const Foo = () => {
  const [fetchData] = useGqlLazyQuery(FOO_GQL);
  useEffect(() => fetchData(), []);
  return <div>...</div>;
};

// Then in another component, maybe sibling, or deep child component
const SomeComponent = () => {
  // Yey, I have access to loading, data, and error here!
  const [, { loading, data, error }] = useGqlLazyQuery(FOO_GQL);
  // We can now do conditional render based on loading and error.
};

Почему я это делаю?

В основном я просто хочу иметь возможность читать состояние загрузки и ошибок из любого компонента в моем приложении. Я смог добиться этого с помощью Redux, но это слишком много, в результате чего два хранилища данных каким-то образом, один внутри клиента Apollo, а другой в Redux. Таким образом, это пустая трата.

Когда я использую apolloClient.readQuery, я могу читать только data, но не loading и error.

Выполнение этого шаблона синглтона Я могу читать data, loading и error из любого места в приложении, исключая использование избыточности.


1. Учитывая этот контекст, каковы недостатки этого?

Я не так много сделал GraphQL, поэтому я не имею в виду много реальных вариантов использования. Единственное, о чем я мог подумать, это:

// Say you need to fetch multiple FOO. I don't know, maybe you have a "compare" page.
const [fetchFoo1, { data: data1, loading: loading1, error: error1 }] = useGqlLazyQuery(FOO_GQL);
const [fetchFoo2, { data: data2, loading: loading2, error: error2 }] = useGqlLazyQuery(FOO_GQL);
// This won't work because data1 and data2 will just point to the same one.
// Same goes for loading1 and loading2, as well as error1 and error2, they're all point to the same value.
// So, in this particular case, we just need to go back to use the original `useLazyQuery`.

2. Каковы преимущества этого? Если есть:)

3. Как сохранить состояние loading и error в приложении, чтобы вы могли получить к ним доступ из любого места в приложении?

...