Reputation: 149
I'm pretty new to using React Js and Javascript as well. I'm wondering how the Dialog below could be refactored into a reusable component since I have duplicate code for another form. Basically, I make a call to my API, and then once the "fetch" is completed, the alert dialog pops out. I was originally thinking of having a separate component and passing along props, but I can't wrap my head around passing props such as dialogText to DialogContent itself.
I posted the Dialog itself below, and also the entire page so there is proper context.
Dialog
<Dialog open={openDialog} onClose={handleCloseDialog}>
<DialogTitle>{"Title"}</DialogTitle>
<DialogContent>
<DialogContentText>
{dialogText}
</DialogContentText>
</DialogContent>
<DialogActions>
<button onClick={handleCloseDialog} autoFocus>Close</button>
</DialogActions>
</Dialog>
Entire code
import React, { useState } from "react";
import Dialog from "@material-ui/core/Dialog";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import Loader from "../../assets/Button";
import handleSaveUser from "../hooks/handleSaveUser";
const NewsLetterForm = () => {
const [loading, setLoading] = useState(false);
const [openDialog, setOpenDialog] = useState(false);
const [dialogText, setDialogText] = useState("");
const [postParams, setPostParams] = useState({
firstName: "",
lastName: "",
email: "",
});
const handleCloseDialog = () => { setOpenDialog(false); };
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
const formData = new FormData(e.target);
const object = {
firstName: formData.get("firstName") ?? "",
lastName: formData.get("lastName") ?? "",
email: formData.get("email") ?? "",
}
setPostParams(postParams);
const apiResponse = await handleSaveUser("newsletter__form", object);
setDialogText(apiResponse);
setOpenDialog(true);
setLoading(false);
};
return (
<form
id='newsletter__form'
onSubmit={handleSubmit}
>
<label htmlFor='firstName' />
<input
name='firstName'
className='__input'
type='text'
id='firstName'
placeholder='First Name'
required
/>
<label htmlFor='lastName' />
<input
name='lastName'
className='__input'
type='text'
id='lastName'
placeholder='Last Name'
required
/>
<label htmlFor='email' />
<input
name='email'
className='__input'
type='text'
id='email'
placeholder='Email'
required
/>
<button
disabled={loading}
type="submit"
value="Subscribe"
>{loading ? <Loader /> : <>Subscribe</>}
</button>
<Dialog open={openDialog} onClose={handleCloseDialog}>
<DialogTitle>{"Some Title"}</DialogTitle>
<DialogContent>
<DialogContentText>
{dialogText}
</DialogContentText>
</DialogContent>
<DialogActions>
<button onClick={handleCloseDialog} autoFocus>Close</button>
</DialogActions>
</Dialog>
</form>
);
};
export default NewsLetterForm;
Upvotes: 0
Views: 1223
Reputation: 4672
You could use the props
to pass the title
content
etc to your CustomDialog
CustomDialog.jsx
const CustomDialog = ({ isOpen, onClose, title, content }) => {
return (
<Dialog open={isOpen} onClose={onClose}>
<DialogTitle>{title}</DialogTitle>
<DialogContent>
<DialogContentText>{content}</DialogContentText>
</DialogContent>
<DialogActions>
<button onClick={onClose} autoFocus>
Close
</button>
</DialogActions>
</Dialog>
);
};
Which you can use in your NewsLetterForm
like so
import CustomDialog from "./CustomDialog";
const NewsLetterForm = () => {
const [loading, setLoading] = useState(false);
const [openDialog, setOpenDialog] = useState(false);
const [dialogText, setDialogText] = useState("");
const handleSubmit = async (e) => {
e.preventDefault();
...
setPostParams(postParams);
const apiResponse = await handleSaveUser("newsletter__form", object);
setDialogText(apiResponse);
setOpenDialog(true);
setLoading(false);
};
return (
<form>
...
<CustomDialog
isOpen={openDialog}
onClose={handleCloseDialog}
title="Some title"
content={dialogText}
/>
</form>
);
};
Upvotes: 1