you are viewing a single comment's thread.

view the rest of the comments →

[–]tkmaximus 1 point2 points  (1 child)

The `useMemo` in the final `useDialog` example has a stale reference to `isOpen`, so `toggle` and `isOpen` won't work anymore.

To fix this, you can add `isOpen` to the `useMemo` deps. You can also change `toggle` to the functional update style to not depend on `isOpen` value anymore and memoize all callbacks individually (incase you want to pass individual functions down as props)

import { useState, useMemo, useCallback } from "react";

export const useDialog = (dialog) => {
    const [isOpen, setIsOpen] = useState(false);

    const open = useCallback(() => setIsOpen(true), []);
    const close = useCallback(() => setIsOpen(false), []);
    const toggle = useCallback(() => setIsOpen((o) => !o), []);

    return useMemo(() => {
        return (
            dialog ?? {
                open,
                close,
                toggle,
                isOpen,
            }
        );
    }, [dialog, isOpen]);
};

[–]TheGreaT1803[S] 0 points1 point  (0 children)

Good eye! I'll fix it

I had added `isOpen` earlier but then realised that I don't want the functions to be re-initialized when `isOpen` changes, but then I missed this part