charbs29
charbs29

Reputation: 149

Creating reusable component with @material-ui/Dialog

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

Answers (1)

RubenSmn
RubenSmn

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

Related Questions