I should start by saying I like the article and have yet to see anyone come up with an elegant solution to the problem. I agree that the closure variable is an anti-pattern and documented in the react teams blog as one of the most common. I solved this issue using signals.js to create an on-demand pub-sub which could be disconnected on unmount and personally I like the elegance of the execution path.
I wrote the code for an employer so cannot copy and paste it but above is the general idea/approach.
I actually like how the solution turned out and feel that it is clean albeit a little unintuitive as you then execute a Promise<void>
I should also clarify that I am not a fan of the cancellable promise approach either. IMO, the dispatcher pub/sub link in a hook is the cleanest implementation I've seen to date.
The link above is not actually referring to a closure variable but the general approach of tracking mounted to avoid the condition is the reason ismounted() was cited as being removed and it forming an antipattern.
Some comments have been hidden by the post's author - find out more
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I should start by saying I like the article and have yet to see anyone come up with an elegant solution to the problem. I agree that the closure variable is an anti-pattern and documented in the react teams blog as one of the most common. I solved this issue using signals.js to create an on-demand pub-sub which could be disconnected on unmount and personally I like the elegance of the execution path.
pseudo-code:
const useAsyncState = <TResult, TArgs>(promise: (...args: TArgs) => Promise<T>, cb: (v: T) => void): (...args: TArgs) => Promise<void> => {
const dispatcher = useMemo(() => new Signal<TResult>(), []);
useEffect(() => {
dispatcher.add(cb);
return () => dispatcher.clear();
}, [dispatcher, cb]);
return (...args: TArgs) => promise(...args).then(dispatcher.emit);
}
usage:
const [state, setState] = useState(undefined);
const loadData = useAsyncState(someAsyncMethod, setState);
useEffect(() => {
loadData();
}, [loadData]);
I wrote the code for an employer so cannot copy and paste it but above is the general idea/approach.
I actually like how the solution turned out and feel that it is clean albeit a little unintuitive as you then execute a Promise<void>
Thanks for sharing.
Can you link to where the React team documents that the closure variable is an anti-pattern? Thanks!
reactjs.org/blog/2015/12/16/ismoun...
I should also clarify that I am not a fan of the cancellable promise approach either. IMO, the dispatcher pub/sub link in a hook is the cleanest implementation I've seen to date.
The link above is not actually referring to a closure variable but the general approach of tracking mounted to avoid the condition is the reason ismounted() was cited as being removed and it forming an antipattern.