React useEffect 清理函数依赖于 async await 结果
React useEffect cleanup function depends on async await result
我有一个反应组件,它异步获取一些资源,然后订阅资源变化。
问题是清除函数不在这个资源的关闭中:
useEffect(() => {
const onResourceChange = () => {
console.log('resource changed');
};
getSomeResource().then(resource => {
resource.subscribe(onResourceChange);
});
return () => {
resource.unsubscribe(onResourceChange); // Error! resource is undefined
}
}, []);
由于在 useEffect
中使用异步函数是不允许的,在 useEffect
的清理函数中取消订阅此资源的最佳方法是什么?
这是一个解决方案,可能是丑陋的...但仍然是一个解决方案:)
useEffect(() => {
const onResourceChange = () => {
console.log('resource changed');
};
let data = {};
getSomeResource().then(resource => {
data.resource = resource;
resource.subscribe(onResourceChange);
});
return () => {
data.resource && data.resource.unsubscribe(onResourceChange); // Error! resource is undefined
};
}, []);
我看到这里有两个 "side effects"。
- 获取资源(需要发生一次,依赖
[]
)
- Subscribe/unsubscribing 回调(需要发生在资源变化、依赖、
[resource]
)
所以我
- 将它们分成两个 "effects"(步骤,每个处理一个副作用)
- 并将其提取到自定义挂钩中
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
只负责获取"resource",而第二个useEffect
负责un/subscribing回调。
并查看每个useEffect
中的deps
列表(前者为空[]
而后者依赖[resource]
)
我有一个反应组件,它异步获取一些资源,然后订阅资源变化。
问题是清除函数不在这个资源的关闭中:
useEffect(() => {
const onResourceChange = () => {
console.log('resource changed');
};
getSomeResource().then(resource => {
resource.subscribe(onResourceChange);
});
return () => {
resource.unsubscribe(onResourceChange); // Error! resource is undefined
}
}, []);
由于在 useEffect
中使用异步函数是不允许的,在 useEffect
的清理函数中取消订阅此资源的最佳方法是什么?
这是一个解决方案,可能是丑陋的...但仍然是一个解决方案:)
useEffect(() => {
const onResourceChange = () => {
console.log('resource changed');
};
let data = {};
getSomeResource().then(resource => {
data.resource = resource;
resource.subscribe(onResourceChange);
});
return () => {
data.resource && data.resource.unsubscribe(onResourceChange); // Error! resource is undefined
};
}, []);
我看到这里有两个 "side effects"。
- 获取资源(需要发生一次,依赖
[]
) - Subscribe/unsubscribing 回调(需要发生在资源变化、依赖、
[resource]
)
所以我
- 将它们分成两个 "effects"(步骤,每个处理一个副作用)
- 并将其提取到自定义挂钩中
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
只负责获取"resource",而第二个useEffect
负责un/subscribing回调。
并查看每个useEffect
中的deps
列表(前者为空[]
而后者依赖[resource]
)