I've tried several solutions to fix this problem, and none have worked.
I have a third-party library that calls an asynchronous function to load something to render in the DOM.
I have a component that wraps the library for the DOM piece and when it finishes I want to be able to call an onComplete
method with it.
Everything works fine. However when I call the onComplete
function, and then inside that function is a call to dispatch
something to a context
it blows up and gives me the
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
export function ParentComponent(props: any) {
const dispatch: any = React.useContext(dispatchContext);
const onComplete = React.useCallback(
(data: any) => {
if (dispatch !== null && dispatch !== undefined) {
dispatch({
payload: { new_data: "thing" },
type: dispatchType.UPDATING
});
}
},
[dispatch]
);
return (
<div>
<ChildComponent onComplete={onComplete} />
</div>
);
}
interface IProp {
onComplete?: function;
}
export function ChildComponent(props: IProp) {
React.useEffect(() => {
if (library.is_ready) {
library.load(data).then(
() => {
console.log("Success");
props.onComplete(library);
},
(error: any) => {
console.error("ERROR");
}
);
}
}, [library]);
return <div id="library-dom-element"></div>;
}
If I comment out the dispatch
function this won't blow up.
It blows up when the asynchronous function is completed and calls the onComplete
function which calls the dispatch
ChildComponent.libary.is_ready
→ ChildComponent.libary.load
→ ChildComponent.libary.onComplete
→ ParentComponent.onComplete
→ dispatch
I have tried adding useCallback
to everything. I have tried using useRef
to track an is_mounted
variable to determine if the DOM pieces are loading correctly.
I just cannot figure out how to call dispatch
on the completion of the third party library.
That's literally it.
Can anyone help or provide guidance on this? I thought I understood how these pieces work together, but I'm missing something.
The application I've been making has been pretty complex.
The bug I provided here is a result of component initialization order that arises because of how I am toggling state.
When I created a delay function to help buffer initialization this resolved the issue for the time being.
Apologies for this question as the design pattern does appear to work, there just needs to be accounting for how your React application's complexity is being managed.
Thank you to everyone who took a look :) <3