如何将@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
相关产品推荐
相关产品推荐

