Search code examples
javascriptreactjstypescriptreact-hooksreact-context

React Hook - Cannot Call Parent Component Dispatch in Child Component onComplete Callback


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.

Code

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_readyChildComponent.libary.loadChildComponent.libary.onCompleteParentComponent.onCompletedispatch

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.


Solution

  • 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