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

React如何在App类组件中使用Modal组件及封装自定义模态框

实现步骤

1. 调整App组件逻辑

首先在App组件的state中新增模态框控制与编辑数据存储字段,补充编辑、保存、关闭模态框的相关方法,修正原代码中DOM属性使用错误(React中使用className代替原生class)、table结构错误问题。
修改后的App组件代码如下:

import React, { Component } from 'react';
import EditModal from './EditModal'; // 引入后面封装的自定义模态框组件

class App extends Component {
  state = {
    lists: [],
    isModalOpen: false, // 控制模态框显隐
    editingItem: null // 存储当前待编辑的行数据
  }

  componentDidMount() {
    fetch('URL')
    .then(res => res.json())
    .then((data) => {
      this.setState({ lists: data })
    })
    .catch(console.log)
  }

  // 点击编辑按钮触发
  handleEdit = (item) => {
    this.setState({
      editingItem: item,
      isModalOpen: true
    })
  }

  // 保存编辑后的数据
  handleSaveEdit = (updatedItem) => {
    const newLists = this.state.lists.map(item => 
      item.orderNo === updatedItem.orderNo ? updatedItem : item
    )
    this.setState({
      lists: newLists,
      isModalOpen: false,
      editingItem: null
    })
    // 此处可补充编辑结果提交后端接口的逻辑
  }

  // 关闭模态框
  handleCloseModal = () => {
    this.setState({
      isModalOpen: false,
      editingItem: null
    })
  }

  render() {
    return (
      <div className="container">
        <table className="table-sm">
          <thead className="thead-dark">
            <tr className="table-bordered">
              <th>Order Number</th>
              <th>Delivery Date</th>
              <th>Customer</th>
              <th>Tracking number</th>
              <th>Status</th>
              <th>Consignee</th> 
              <th>Edit</th> 
              <th>Delete</th> 
            </tr>
          </thead>
          <tbody className="table-bordered">
            {this.state.lists.map(listInfo => (
              <tr key={listInfo.orderNo}>
                <td>{listInfo.orderNo}</td>
                <td>{listInfo.date}</td>
                <td>{listInfo.customer}</td>
                <td>{listInfo.trackingNo}</td>
                <td>{listInfo.status}</td>
                <td>{listInfo.consignee}</td>
                <td>
                  <button 
                    type="button" 
                    className="btn btn-primary"
                    onClick={() => this.handleEdit(listInfo)}
                  >
                    编辑
                  </button>
                </td>
                <td><button className="btn btn-danger">删除</button></td>
              </tr>
            ))}
          </tbody>
        </table>
        {/* 引入自定义模态框组件,传入对应参数 */}
        <EditModal 
          visible={this.state.isModalOpen}
          editData={this.state.editingItem}
          onClose={this.handleCloseModal}
          onSave={this.handleSaveEdit}
        />
      </div>
    );
  }
}

export default App;

2. 封装自定义模态框组件

新建EditModal.js文件,编写独立可复用的模态框组件,所有交互逻辑通过props和父组件通信:

import React, { Component } from 'react';

class EditModal extends Component {
  state = {
    // 初始化表单数据
    formData: {
      orderNo: '',
      date: '',
      customer: '',
      trackingNo: '',
      status: '',
      consignee: ''
    }
  }

  // 监听编辑数据变化,更新表单
  componentDidUpdate(prevProps) {
    if (prevProps.editData !== this.props.editData && this.props.editData) {
      this.setState({ formData: this.props.editData })
    }
  }

  // 表单输入同步
  handleInputChange = (e) => {
    const { name, value } = e.target;
    this.setState(prev => ({
      formData: { ...prev.formData, [name]: value }
    }))
  }

  // 提交保存
  handleSubmit = () => {
    this.props.onSave(this.state.formData)
  }

  render() {
    const { visible, onClose } = this.props;
    const { formData } = this.state;
    if (!visible) return null;

    return (
      <div className="modal fade show" style={{display: 'block'}} tabIndex="-1" role="dialog">
        <div className="modal-dialog" role="document">
          <div className="modal-content">
            <div className="modal-header">
              <h5 className="modal-title">编辑订单信息</h5>
              <button type="button" className="close" onClick={onClose}>
                <span>&times;</span>
              </button>
            </div>
            <div className="modal-body">
              <div className="form-group">
                <label>订单号</label>
                <input
                  type="text"
                  className="form-control"
                  name="orderNo"
                  value={formData.orderNo}
                  onChange={this.handleInputChange}
                  disabled
                />
              </div>
              <div className="form-group">
                <label>交货日期</label>
                <input
                  type="date"
                  className="form-control"
                  name="date"
                  value={formData.date}
                  onChange={this.handleInputChange}
                />
              </div>
              {/* 剩余字段按照上面的格式补充即可 */}
              <div className="form-group">
                <label>客户</label>
                <input
                  type="text"
                  className="form-control"
                  name="customer"
                  value={formData.customer}
                  onChange={this.handleInputChange}
                />
              </div>
            </div>
            <div className="modal-footer">
              <button type="button" className="btn btn-secondary" onClick={onClose}>取消</button>
              <button type="button" className="btn btn-primary" onClick={this.handleSubmit}>保存</button>
            </div>
          </div>
        </div>
      </div>
    )
  }
}

export default EditModal;

3. 全局调用模态框的实现

如果需要在index.js中直接调用该模态框(不依附于App组件的层级),可以使用React的createPortal方法将模态框挂载到全局body节点,示例如下:

// index.js 中修改
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import EditModal from './EditModal';

// 如果需要全局控制模态框,可以单独维护模态框的状态
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
    {/* 全局挂载的模态框,可通过全局状态/事件总线控制显隐 */}
    {/* <EditModal visible={globalModalVisible} ...其他props /> */}
  </React.StrictMode>
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 15:24:03