You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将@material-ui/Dialog重构为React可复用组件?

重构Material-UI Dialog为可复用组件

步骤1:创建独立的可复用Dialog组件

新建ApiResponseDialog.js文件,将Dialog逻辑封装成接收props的组件,方便在多个表单中复用:

import React 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";

const ApiResponseDialog = ({ open, onClose, title, content }) => {
  return (
    <Dialog open={open} onClose={onClose}>
      <DialogTitle>{title}</DialogTitle>
      <DialogContent>
        <DialogContentText>{content}</DialogContentText>
      </DialogContent>
      <DialogActions>
        <button onClick={onClose} autoFocus>Close</button>
      </DialogActions>
    </Dialog>
  );
};

export default ApiResponseDialog;

这个组件接收4个核心props:

  • open:控制对话框显示状态的布尔值
  • onClose:关闭对话框的回调函数
  • title:对话框标题文本
  • content:对话框展示的内容文本(对应原代码中的dialogText)

步骤2:在原表单组件中使用复用组件

修改NewsLetterForm.js,导入新建的组件并替换原Dialog代码:

import React, { useState } from "react";

// 导入复用的Dialog组件
import ApiResponseDialog from "./ApiResponseDialog";

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") ?? "",
        }
        // 修正原代码小问题:将表单数据存入state
        setPostParams(object);
        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组件,传递对应props */}
            <ApiResponseDialog
                open={openDialog}
                onClose={handleCloseDialog}
                title="Some Title"
                content={dialogText}
            />
        </form>
    );
};

export default NewsLetterForm;

扩展建议

如果需要适配更多场景,可给复用组件添加可选props:

  • confirmText:自定义确认按钮文本
  • onConfirm:确认按钮的回调函数
  • variant:控制Dialog样式变体

内容的提问来源于stack exchange,提问作者charbs29

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:20:25