【问题标题】:memoized a closure and render callback with useCallback使用 useCallback 记住一个闭包和渲染回调
【发布时间】:2019-11-01 06:39:00
【问题描述】:

让我有一个 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. 我收到 linter 警告说我应该添加 markAsViewed 作为依赖等等等等。我不能,因为它会触发无限循环(因为每次都不同的参考)
  2. 使用&lt;MarkAsViewed /&gt; 组件的每个人都需要手动记忆

理想情况下这是我想要的,但它是无效代码,因为“markAsViewed”不是反应组件,不能有 useCallback

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

知道如何解决这个问题吗?

注意:我们还没有准备好将 Apollo 版本更新为挂钩

【问题讨论】:

  • 嗯,我认为最好的解决方案实际上是使用内置的 Apollo React 钩子,但如果你不能这样做,你可以自己动手。您可以构建一个自定义 useMutation 挂钩并在其中使用 useCallback 。早期版本的 React-Apollo 也有一个 Mutation 组件,它可以为您解决大部分问题。
  • 好吧 MarkAsViewedMutation 实际上是一个 Apollo Mutation 组件,它有不同的名称,因为它只是一个类型化的版本
  • 你可以试试:const alwaysSameRefFunc = useCallback(markAsViewed, []}

标签: reactjs graphql apollo


【解决方案1】:

以下是否有效?

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 组件的渲染方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 2020-01-22
    • 2021-11-11
    相关资源
    最近更新 更多