Home > Blockchain >  State messiness trying to open a dialog, yet allowing the dialog to close itself
State messiness trying to open a dialog, yet allowing the dialog to close itself

Time:10-23

I'm prototyping a new version of our application in React 18. I'm somewhat new to React and have stumbled upon a scenario that has a few different problems.

We need to open a modal/dialog when a user performs an action. They will click a button to edit data, that opens a dialog window with a form. When they close the dialog, the form data is passed back to the component which opened it.

In our old app, it would be something like const user = new UserModal(123)

I'm using BlueprintJS's Dialog component for this, but this issue is applicable to any library.

I'm writing a wrapper because all of our modals will have similar functionality so the props to the Dialog component will never change outside of whether it's open or not.

Here's a super basic example of this "wrapper" component:

export const Modal = ({ isOpen }: ModalProps) => {
    const [isOpen2, setIsOpen] = useState(isOpen);
    const handleClose = useCallback(() => {
      setIsOpen(false);
    }, []);
  
    return (
        <Dialog isOpen={isOpen2}>
          <p>this is a dialog</p>
          <Button onClick={handleClose} text="close" />
        </Dialog>
    );
}

Using this in the parent would look like this:

const Demo = () => {
  const [isOpen, setIsOpen] = useState(false);

  // some code calls setIsOpen(true) when we need to open the modal

  return <Modal isOpen={isOpen} />;
}

This presents multiple problems:

  • A parent controller can trigger this dialog to open, but never close (interacting with the app is prevented while a modal is open)
  • The modal can close itself via an X or "Cancel" button
  • This leads to two useState invocations - one in the parent controller and one inside the modal. This doesn't work right by itself, because once the state is set in the controller, it can't update when the prop changes with more code
  • The parent controller would need to know when it closes so it can update it's own state value.
  • I really dislike having to put <Modal> elements in the parent jsx, I liked the new UserModal code but that might be a fact of life

Overall, this feels like a very wrong approach. How can I design this to be more "proper" and yet work the way I need?

CodePudding user response:

you can pass your method from parent to child and call there and also you can use 1 state for manage modal status.

export const Modal = ({ isOpen, handleClose, closeCallBack }: ModalProps) => {
const handleCloseChild = () =>{
 closeCallBack()
 handleClose()
}

return (
    <Dialog isOpen={isOpen}>
      <p>this is a dialog</p>
      <Button onClick={handleCloseChild} text="close" />
    </Dialog>
 );
}

and parent something like this

const Demo = () => {
  const [isOpen, setIsOpen] = useState(false);

  // some code calls setIsOpen(true) when we need to open the modal
  const handleClose = () =>{
   setIsOpen(false)
  }
  return <Modal isOpen={isOpen} handleClose={handleClose} closeCallBack={() => // do what you want on close modal or you just do this in side modal or even in handelClose function }  />;
}
  • Related