I have the below function which calls show a modal dialog on click of edit button. How do I render the functional component UpdateModal
from function showModal?
Here is the function:
const showModal = (user: IUser) => {
setShowUpdateModal(true);
return (
<>
<div>Hello</div>
<UpdateModal
user={user}
showUpdateModal={showUpdateModal}
setShowUpdateModal={
(bool: boolean | ((prevState: boolean) => boolean)) =>
setShowUpdateModal(bool)
}
/>
</>
);
}
UpdateModal:
import React, { FC } from 'react';
import { Modal } from 'react-bootstrap';
import styles from "../../styles/user.module.css";
import UpdateUser from './update.user';
import { IUser } from '../../models/user';
type updateModalProps = {
setShowUpdateModal: (open: boolean) => void;
showUpdateModal: boolean,
user: IUser
};
const UpdateModal: FC<updateModalProps> = ({
setShowUpdateModal,
showUpdateModal,
user
}) => {
console.log("showUpdateModal....", showUpdateModal);
return (
<Modal showUpdateModal={showUpdateModal}>
<Modal.Dialog>
<Modal.Header closeButton onClick={() => setShowUpdateModal(false)}>
<Modal.Title className={`${styles.createText}`}>
Create User Form
</Modal.Title>
</Modal.Header>
<Modal.Body>
<UpdateUser user={user} setShowUpdateModal={setShowUpdateModal} />
</Modal.Body>
</Modal.Dialog>
</Modal>
);
}
export default UpdateModal;
User.tsx:
import UpdateModal from './update-modal';
function UserContent() {
const [showUpdateModal, setShowUpdateModal] = useState(false);
const showModal = (user: IUser) => {
setShowUpdateModal(true);
return (
<>
<div>Hello</div>
<UpdateModal
user={user}
showUpdateModal={showUpdateModal}
setShowUpdateModal={
(bool: boolean | ((prevState: boolean) => boolean)) =>
setShowUpdateModal(bool)
}
/>
</>
);
// return (<><div>Hello</div> <UpdateModal user={user} showUpdateModal={showUpdateModal} setShowUpdateModal={(bool: boolean | ((prevState: boolean) => boolean)) => setShowUpdateModal(bool)} /></>);
}
return (
<div>
<Table responsive striped bordered hover variant="light">
<thead>
<tr>
</tr>
</thead>
<tbody>
{data && data.map((user, i) => (
<tr key={user._id}>
....
<td>
<Pen
color="black"
size={20}
onClick={() => { showModal(user); }}
/>
</td>
</tr>
))}
</tbody>
</Table>
</div>
);
}
// display Users
const User = () => {
return (
<UserContent />
)
}
export default User;
2
Answers
The issue is that you can’t return JSX from a callback function and expect React to know it needs to render it somewhere.
The
showModal
callback can update theshowUpdateModal
state and the parent component will be rerendered with the updated state value. From here you just render the modal as part of the render return of the parent component.Update the
showUpdateModal
state to hold a reference to a specific user, or a null value. Pass this to the modal’suser
prop. All the modal closing actions should set theshowUpdateModal
state back tonull
to close the model.Example:
I think you need to conditionally render the
UpdateModal
component in the returned value ofUserContent
. Conceptually this is the flow most often seen:This code will trigger rerender when clicking
Pen
because state changes. Then, becauseshowUpdateModal
istrue
,UpdateModal
will be rendered. However this will require you to reorganize your code significantly.