简体   繁体   中英

How do I reset props from a parent component in a child component?

I'm trying to trigger a modal to appear when there is an error in my form.

On my app.js file I have this handler function which is called when a field is blank:

  const [modalShow, setModalShow] = useState(false);
  const [modalMessage, setModalMessage] = useState('');

  const alertModalHandler = () => {
    setModalShow(true);
    setModalMessage('User name field blank');
  }

These props are in turn sent to a modal component on Modal.js:

<AlertModal modalOpen={modalShow} modalText={modalMessage}/>

On Modal.js I have it so it uses useEffect to read the props and set an open/close state on the modal component.

const AlertModal = (props) => {

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

  useEffect(() => {if (props.modalOpen) {
    setIsOpen(true);
  }}, [props.modalOpen])

  const handleClose = () => setIsOpen(false);

  return (
    <Modal show={isOpen} onHide={handleClose}>
      <Modal.Header closeButton>Alert</Modal.Header>
      <Modal.Body>{props.modalText}</Modal.Body>
    </Modal>
  );
};

export default AlertModal;

This works...but only once as I can't seem to reset modalShow from within modal.js when the modal is closed (when isOpen is false).

Would anyone know how I can do this?

My full App.js code is:

import React, { useState } from 'react';
import './App.css';
import 'bootstrap/dist/css/bootstrap.css';
import AddUserForm from './components/addUserForm';
import UserList from './components/userList';
import AlertModal from './components/modal';

function App() {

  const [users, setUsers] = useState([]);
  const [modalShow, setModalShow] = useState(false);
  const [modalMessage, setModalMessage] = useState('');

  const addPersonHandler = (nameValue, ageValue) => {
    setUsers(prevUsers => {
      const updatedUsers = [...prevUsers];
      updatedUsers.unshift({ name: nameValue, age: ageValue });
      return updatedUsers;
    });
  };

  const alertModalHandler = () => {
    setModalShow(true);
    setModalMessage('User name field blank');
  }

  let content = (
    <p style={{ textAlign: 'center' }}>No users found. Maybe add one?</p>
  );

  if (users.length > 0) {
    content = (
      <UserList items={users} />
    );
  }

  return (
    <>
      <div className="container">
        <div className="row">
          <div className="col-md-6 offset-md-3">
            <AddUserForm onAddPerson={addPersonHandler} fireAlertModal={alertModalHandler}/>
          </div>
        </div>
        <div className="row">
          <div className="col-md-6 offset-md-3">
            {content}
          </div>
        </div>
      </div>
      <AlertModal modalOpen={modalShow} modalText={modalMessage}/>
    </>
  );
}

export default App;

In App.js , pass as props setModalShow to AlertModal like so:

<AlertModal modalOpen={modalShow} modalText={modalMessage} setModalShow={setModalShow}/>

Then in AlertModal.js (notice I simplified the code, for what you want to do, you don't need that state and useEffect ):

const AlertModal = (props) => {

  return (
    <Modal show={props.modalOpen} onHide={()=> props.setModalShow(false)}>
      <Modal.Header closeButton>Alert</Modal.Header>
      <Modal.Body>{props.modalText}</Modal.Body>
    </Modal>
  );
};

export default AlertModal;

Do not create a derived state from props, instead pass a callback from parent to child and maintain the state in the parent.

App

const alertModalHandler = () => {
  setModalShow(true);
  setModalMessage("User name field blank");
};

const handleModalClose = () => setModalShow(false);

Pass handleModalClose as handleClose prop to AlertModal component

<AlertModal modalOpen={modalShow} modalText={modalMessage} handleClose={handleModalClose}/>

AlertModal

const AlertModal = (props) => {
  return (
    <Modal show={props.modalShow} onHide={props.handleClose}>
      <Modal.Header closeButton>Alert</Modal.Header>
      <Modal.Body>{props.modalText}</Modal.Body>
    </Modal>
  );
};

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