javascript - React useEffect 清理功能依赖于异步等待结果
问题描述
我有一个反应组件,它异步获取一些资源,然后订阅资源更改。
问题是清理功能不在此资源的关闭中:
useEffect(() => {
const onResourceChange = () => {
console.log('resource changed');
};
getSomeResource().then(resource => {
resource.subscribe(onResourceChange);
});
return () => {
resource.unsubscribe(onResourceChange); // Error! resource is undefined
}
}, []);
由于useEffect
不允许在其中使用异步函数,那么在useEffect
的清理函数中取消订阅该资源的最佳方法是什么?
解决方案
我看到这里有两个“副作用”。
- 获取资源(需要发生一次,依赖
[]
) - 订阅/取消订阅回调(需要在资源更改、依赖项时发生
[resource]
)
所以我
- 将它们分成两个“效果”(步骤,每个处理一个副作用)
- 并将其提取到自定义钩子中
function useResource() {
const [resource, setResource] = useState(undefined)
const onResourceChange = () => console.log('resource changed');
// Get the resource, initially.
useEffect(() => {
getSomeResource(setResource)
}, [])
// When the resource is retrieved (or changed),
// the resource will subscribe and unsubscribe
useEffect(() => {
resource.subscribe(onResourceChange)
return () => resource.unsubscribe(onResourceChange)
}, [resource])
}
// Use it like this
function App() {
useResource()
return <>your elements</>
}
如您所见,第一个useEffect
只负责获取“资源”,而第二个useEffect
负责取消/订阅回调。
并查看deps
每个列表useEffect
(前者为空[]
,后者取决于[resource]
)
推荐阅读
- xamarin - 一个一个循环值
- javascript - 简单的 javascript 获取到 php
- php - 带有左连接的sql查询以获取名字
- google-cloud-platform - GCP stackdriver enteries列表分页问题
- javascript - 用于将 JSON 存储到变量的回调函数
- javascript - reactjs中嵌套元素,多级数组的设置状态
- python - if, else 即使条件为真也返回 else 值,在 for 循环中
- django - 在 django 中截断文本
- c - Minifilter 驱动程序 Windows 10 之前和包括 1809 和 1903 及更高版本之间的差异(在创建文件时调用 FileRenameInformation)
- laravel - 播种具有多个关系的表?