запомнили закрытие и обработали обратный вызов с помощью useCallback - PullRequest
1 голос
/ 31 октября 2019

давайте у меня будет компонент мутации graphql, который я буду использовать во многих местах

const MarkAsViewed =({ type = 1, children }) => {
  const markAsViewed = (commitMutation) => (type) => {
    return commitMutation({
      variables: { type }
    });
  };

  return (
    <MarkAsViewedMutation
      mutation={MARK_AS_VIEWED_MUTATION}
      variables={{
        type,
      }}
    >
      {
        (commitMutation, { error, loading }) => children({
          markAsViewed: markAsViewed(commitMutation)
        })
      }
    </MarkAsViewedMutation>
  );
};

однако, поскольку markAsViewed является функцией замыкания, она всегда будет возвращать разные функции с разными ref, что означает разные для реакции.

это заставляет дочерний компонент выполнять useCallback как:

const alwaysSameRefFunc = useCallback(()=>{ markAsViewed(), []}

выше работает, но создает 2 проблемы:

  1. Я получаю линтерпредупреждение, сказав, что я должен добавить markAsViewed в качестве зависимости, бла-бла. что я не могу, потому что он запускает бесконечный цикл (так как каждый раз разные ссылки)
  2. каждый, кто использует компонент <MarkAsViewed />, должен будет вручную запоминать

В идеале это то, что я хочу, но это неверный код, потому что «markAsViewed» не является компонентом реакции и не может использовать useCallback

const markAsViewed = (commitMutation) => useCallback((type) => {
    return commitMutation({
      variables: { type }
    });
  }, []);

. Любая идея, как я могу решить проблему?

примечание: мы не готовыобновить версию Apollo, чтобы иметь hoook еще

1 Ответ

0 голосов
/ 01 ноября 2019

Работает ли следующее?

const markAsViewed = commitMutation => type => {
  return commitMutation({
    variables: { type },
  });
};
const MarkAsViewed = ({ type = 1, children }) => {
  const fn = useCallback(
    (commitMutation, { error, loading }) =>
      children({
        markAsViewed: markAsViewed(commitMutation),
      }),
    [children]
  );
  return (
    <MarkAsViewedMutation
      mutation={MARK_AS_VIEWED_MUTATION}
      variables={{
        type,
      }}
    >
      {fn}
    </MarkAsViewedMutation>
  );
};

Я не уверен, будет ли это работать, потому что это все еще зависит от дочерних элементов, если это вызывает ненужные визуализации, тогда, возможно, опубликуйте, как отображается компонент MarkAsViewed.

...