skip to Main Content

I have a parent component:

interface AlbumListProps {
    albums: AlbumType[];
}

const AlbumList = (props: AlbumListProps) => {
    const [open, setOpen] = useState(false);

    let albumToEdit;

    const handleEdit = () => {
        setOpen(true);
    };

    return (
        <>
          <button onClick={handleEdit} > Edit </button>
          <Modal openModal={open} />
        </>
    );
};

And child component which is a modal window.

const Modal = (props: any) => {
    const { openModal } = props;
    const [open, setOpen] = useState(openModal);

    const cancelButtonRef = useRef(null);

    return (
      <Transition.Root show={open} as={Fragment}>
        <Dialog as='div' initialFocus={cancelButtonRef} onClose={setOpen} >
          <Transition.Child as={Fragment} > 
           <Dialog.Panel>
            <Dialog.Title> Some text </Dialog.Title>
            <button type='button' onClick={() => setOpen(false)} 
                  ref={cancelButtonRef} > Cancel </button> 
            </Dialog.Panel>
          </Transition.Child>
        </Dialog>
      </Transition.Root>
    );
};

As you can see I’m passing true with onClick={handleEdit} via openModal props down to Modal component.
In Modal component I’m setting up the initial state with the value received from props.openModal, unfortunately, the modal window don’t open.

I think the issue is in AlbumList component as when I’m setting up open to true with const [open, setOpen] = useState(true) Modal window shows up.

3

Answers


  1. The problem is that the initial state of the child component is only set once when the component is first rendered.

    you can make it update each time openModal is updated:

    useEffect(() => {
      setOpen(openModal);
    },[openModal]);
    

    you can also use openModal directly you don’t really need create a state in the child component and here:

    <button type='button' onClick={() => props.setOpen(false)}> Cancel </button>
    

    with passing also setOpen function as props to to child:

    <Modal 
     openModal={open} 
     setOpen={setOpen}
    />
    
    Login or Signup to reply.
  2. why not just skip the second set of state and do…

    ...return (
         <Transition.Root show={openModal} as={Fragment}>...
    

    That way is more efficient and easier to follow / debug.

    Login or Signup to reply.
  3. You could change this:

    const handleEdit = () => {
            setOpen(true);
        };
    

    to this:

    const handleEdit = () => setOpen(!open);
    

    and then pass handleEdit as prop to Modal. Then your onClick prop for the button inside Modal would be handleEdit.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search