简体   繁体   中英

React: Trigger a function from React Modal component

UPDATE: Code Sandbox link - https://codesandbox.io/s/goofy-dubinsky-4ui5v?file=/src/SearchRow.js

There is a use-case where we have a search results table and there are some rows that have a button to audit that row data for business purposes. Now when the user clicks on that button we need to prompt the user for confirmation and we are stuck on how to trigger this.

WHAT TO DO IN TODO PART (SearchRow.js)?

Here is the main SearchResultsPage.js

return (
  {results.map((searchRow) => {
    <SearchRow content={searchRow.content} showSaveButton={searchRow.content.id === 10} />
  });
);

SearchRow.js

function SearchRow({content, showSaveButton}) {
  const getConfirmation = (event) => {
     // TODO: Call Modal.js, if user presses yes then call the saveProductData function, otherwise return
  }

  const saveProductData = async () => {
    await axios.post("url", content);
  }

  <div>
    <p>{content.title}</p>
    {showSaveButton && 
      <Button variant="primary" onClick={(e) => getConfirmation(e)} />
    }
  </div>
}

Finally Modal.js

function Modal({
  heading,
  message,
  buttonSuccess = "Yes",    
  buttonFailure = "No",
  showModal = false,
}) {
  const [show, setShow] = useState(showModal);

  return (
    <BootstrapModal show={show} onHide={setShow(false)}>
      <BootstrapModal.Header closeButton>
        <BootstrapModal.Title>{heading}</BootstrapModal.Title>
      </BootstrapModal.Header>
      <BootstrapModal.Body>{message}</BootstrapModal.Body>
        <BootstrapModal.Footer>
          <Button variant="secondary" onClick={setShow(false)}>
            {buttonSuccess}
          </Button>
          <Button variant="primary" onClick={setShow(false)}>
            {buttonFailure}
          </Button>
       </BootstrapModal.Footer>
    </BootstrapModal>
  );
}

Can someone please help on how to achieve this or if there is any other better approach or any suggestions?

Thanks in advance :)

As far as I can understand, you want to render the modal only once the button is clicked, while that's quite natural for non-react environments, in react it works in a different way. In the simplest solution the Modal should be always rendered, and when a user clicks the button you change the modal open property to true .

So, you can move logic that shows and hides modal from Modal.js to SearchRow.js , and then when user clicks showSaveButton button you can set showModal to true , and in return method check if that variable is truthy, if it is,than display modal, otherwise return null . Second, you pass two functions as props: First one will be executed if " YES " button on modal is pressed, second one will be excuted if " NO " button is pressed.

Here is your modifed code :

SearchRow.js

function SearchRow({content, showSaveButton}) {

  const [showModal,setShowModal] = useState(false);
  
  const displayConfimationModal = (event) => {
     setShowModal(true);
  }
  
  const handleConfirmation = (event) => {
    console.log("confirmed");
    await saveProductData();
    setShowModal(false);
  }
  
  const handleDecline = (event) =>{
    console.log("declined");
    setShowModal(false);
  }

  const saveProductData = async () => {
    await axios.post("url", content);
  }
  
return (
  <div>
    <p>{content.title}</p>
    {showSaveButton && 
      <Button variant="primary" onClick={(e) => displayConfimationModal(e)} />
    }
     {showModal ? ( < Modal onConfirm = {handleConfirmation}  onDecline={handleDecline}/>) : null}
  </div>);
}

Modal.js

function Modal({
  heading="Default heading",
  message="Default message",
  onConfirm,
  onDecline,
  buttonSuccess = "Yes",    
  buttonFailure = "No",
}) {
  

  return (
    <BootstrapModal>
      <BootstrapModal.Header closeButton>
        <BootstrapModal.Title>{heading}</BootstrapModal.Title>
      </BootstrapModal.Header>
      <BootstrapModal.Body>{message}</BootstrapModal.Body>
        <BootstrapModal.Footer>
          <Button variant="secondary" onClick={onConfirm}>
            {buttonSuccess}
          </Button>
          <Button variant="primary" onClick={onDecline}>
            {buttonFailure}
          </Button>
       </BootstrapModal.Footer>
    </BootstrapModal>
  );
}

export default Modal;

My ConfirmationModal wraps my Modal , and allows me to pass in an onConfirm method that I can then call when someone clicks on the success button. I then control my Modal 'show' from my wrapper as well.

Okay so I've figured out how to fix this. Please go through the code sandbox - https://codesandbox.io/s/goofy-dubinsky-4ui5v?file=/src/SearchRow.js

What we were missing is sending Modal show property from parent function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM