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.