I have a react component which gets some resource asynchronously and then subscribes to resource changes.
The problem is that the cleanup function is not in the closure of this resource:
useEffect(() => {
const onResourceChange = () => {
console.log('resource changed');
};
getSomeResource().then(resource => {
resource.subscribe(onResourceChange);
});
return () => {
resource.unsubscribe(onResourceChange); // Error! resource is undefined
}
}, []);
Since using async functions in useEffect
is not allowed, what is the best way to unsubscribe from this resource inside useEffect
's cleanup function?
I see two "side effects" going on here.
[]
) [resource]
) So I
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</>
}
As you can see, the first useEffect
is responsible for fetching the "resource" only, while the 2nd useEffect
is responsible for un/subscribing the callback.
And check out the deps
list in each useEffect
(The former is empty []
while the latter depends on [resource]
)
This is a solution, probably the ugly one... but still a solution :)
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
};
}, []);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.