reactjs - 使用 useCallback 记住一个闭包和渲染回调
问题描述
让我有一个 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 版本更新为 Hook
解决方案
下面的工作吗?
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 组件的渲染方式。
推荐阅读
- mysql - 无法通过 phpmyadmin 连接到 laradock mysql 容器
- python - 从数据库运行时创建模型
- protocol-buffers - 如何根据 protobuf grpc 规范正确格式化响应对象
- docker - 用于 Windows SQL Server 的 Docker 上的 Net Core 无法正常工作
- javascript - 更改传单中的图层 z-index
- c++ - 使用 Qt 信号和槽传递指针
- javascript - 在 Typescript / Javascript 中过滤掉深层嵌套数据结构的对象
- reactjs - 如何处理导致重新渲染的有用参数和函数
- java - 我想从 Eclipse 连接到 SSMS 数据库,但它抛出 SQLserverException
- android-studio - 'getView' 不覆盖任何内容