【发布时间】: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 个问题:
- 我收到 linter 警告说我应该添加
markAsViewed作为依赖等等等等。我不能,因为它会触发无限循环(因为每次都不同的参考) - 使用
<MarkAsViewed />组件的每个人都需要手动记忆
理想情况下这是我想要的,但它是无效代码,因为“markAsViewed”不是反应组件,不能有 useCallback
const markAsViewed = (commitMutation) => useCallback((type) => {
return commitMutation({
variables: { type }
});
}, []);
知道如何解决这个问题吗?
注意:我们还没有准备好将 Apollo 版本更新为挂钩
【问题讨论】:
-
嗯,我认为最好的解决方案实际上是使用内置的 Apollo React 钩子,但如果你不能这样做,你可以自己动手。您可以构建一个自定义 useMutation 挂钩并在其中使用 useCallback 。早期版本的 React-Apollo 也有一个
Mutation组件,它可以为您解决大部分问题。 -
好吧
MarkAsViewedMutation实际上是一个 ApolloMutation组件,它有不同的名称,因为它只是一个类型化的版本 -
你可以试试:
const alwaysSameRefFunc = useCallback(markAsViewed, []}