Jean Pierre
Jean Pierre

Reputation: 321

Call a function in React from child component

Inside a component, there is a mapping for creating multiple elements. Each element can be deleted if a button is clicked:

const ParentComponent = () => {

   ...
   const [fields, setFields] = useState([{value: 'a', editable: false},
                                        [{value: 'b', editable: true},
                                        [{value: 'c', editable: false}]);

   const handleRemoveField = (id) => {
      const values = [...fields];
      values.splice(id, 1);
      setFields(values);
   }

   ...
   
   return (
      ...
      {fields.map((field, id) => {
          return (
             <div>
                ...
                <button onClick={() => handleRemoveField(id)}>delete</button>
             </div>
           );
       })}
      ...
     );

The above code is working fine. The problem comes up when the delete part must be done from a modal component instead of directly clicking the button.

So I created a new Modal component:

const DeleteModal = ({ isDeleteModalOpen, closeDeleteModal }) => {
    return (
        <Modal isOpen={isDeleteModalOpen}>
            <ModalTitle handleClose={closeDeleteModal} />
            <button onClick={deleteElement}> OK </button>
            <button onClick={closeDeleteModal}> cancel </button>
        </Modal>
       );
};

And inside ParentComponent, DeleteModal was imported. When handleRemoveField is called, instead of directly deleting the element it is opening the modal.

What I don't know how to do is to delete de element when OK button from modal is clicked (deleteElement function from modal should do that).

Modified ParentComponent:

const ParentComponent = () => {

   ...
   const [fields, setFields] = useState([{value: 'a', editable: false},
                                        [{value: 'b', editable: true},
                                        [{value: 'c', editable: false}]);

   const handleRemoveField = (id) => { // modified the method to call modal
      openDeleteModal(id); 
   };

   // added for open/close modal
   const [isDeleteModalOpen, setDeleteModalOpen] = useState(false);
       const openDeleteModal = () => {
       setDeleteModalOpen(true);
   };
   const closeDeleteModal = () => setDeleteModalOpen(false);

   ...
   
   return (
      ...
      {fields.map((field, id) => {
          return (
             <div>
                ...
                <button onClick={() => handleRemoveField(id)}>delete</button>
                // imported modal here:
                <DeleteModal
                    isDeleteModalOpen={isDeleteModalOpen}
                    closeDeleteModal={closeDeleteModal} />
             </div>
           );
       })}
      ...
     );

The cancel button is working, it closes the modal. The problem is with OK button that must delete the element.

How can that be done?

Upvotes: 0

Views: 46

Answers (3)

Lu&#239;s
Lu&#239;s

Reputation: 2833

You can add a new prop to your Modal components, maybe something along the lines of onDelete. Than you can pass a method which deletes your element to the Modal like so:

<Modal
  isDeleteModalOpen={isDeleteModalOpen}
  closeDeleteModal={closeDeleteModal}
  onDelete={() => deleteElement(id)}
/>

Inside your Modal component you can call your onDelete prop to call deleteElement(id):

const DeleteModal = ({ isDeleteModalOpen, closeDeleteModal, onDelete }) => {
    return (
        <Modal isOpen={isDeleteModalOpen}>
            <ModalTitle handleClose={closeDeleteModal} />
            <button onClick={onDelete}> OK </button>
            <button onClick={closeDeleteModal}> cancel </button>
        </Modal>
       );
};

So long story short: You can pass down a method with your child component to call it from there.

Upvotes: 2

H&#233;ctor
H&#233;ctor

Reputation: 26034

You could save the ID that is going to be deleted before open modal, and use it to decide if modal is visible or not, as well.

const [idToDelete, setIdToDelete] = useState(null);

const handleRemoveField = (id) => {
    setIdToDelete(id);
};

...    

<DeleteModal isDeleteModalOpen={idToDelete !== null} closeDeleteModal={closeDeleteModal} />

Upvotes: 1

tuan nguyen
tuan nguyen

Reputation: 386

you use an variable to save which item you are deleting

const [itemDel,setItemDel] = React.useState(null);

then, when click edit to show modal, you set that item to itemDel ( in handleRemoveField function)

something like

return (
      <>
      {fields.map((field, id) => {
          return (
             <div>
                ...
                <button onClick={() => handleRemoveField(id)}>delete</button>
             </div>
           );
       })}
  {
       !!itemDel&& <DeleteModal
                    isDeleteModalOpen={isDeleteModalOpen}
                    closeDeleteModal={closeDeleteModal} />
 }
      </>
     );

and, when you done, or want to hide modal, just call setItemDel(null)

Upvotes: 0

Related Questions