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

React新手教程:如何将表单数据渲染至表格组件?

解决方法:通过组件回调传递数据实现表单数据渲染到表格

作为React新手,你遇到的是组件间单向数据流的典型问题——子组件(EventForm)的数据需要传递到顶层父组件(EventList)来完成表格渲染。我们可以通过回调函数逐层传递的方式实现这个需求,具体步骤如下:

步骤1:在EventList中维护事件列表状态

首先,我们需要在最顶层的EventList组件中保存所有事件数据,并定义一个添加新事件的方法,用来接收子组件传来的新数据并更新状态:

import React from "react";
import {Container, Row, Table} from "react-bootstrap";
import EventModal from "./EventModalButton";

class EventList extends React.Component{
  // 初始化事件列表,包含你的模拟数据
  state = {
    events: [
      {
        title: "Python workshop",
        type: "WorkShop",
        time: "12:00PM",
        date: "Saturday, 29/08/2020"
      },
      {
        title: "Pandemic Situation",
        type: "Webinar",
        time: "02:00PM",
        date: "Saturday, 29/08/2020"
      }
    ]
  };

  // 添加新事件的回调:接收子组件传来的新事件,更新状态
  handleAddEvent = (newEvent) => {
    this.setState(prevState => ({
      events: [...prevState.events, newEvent]
    }));
  };

  render() {
    return (
      <Container fluid="md">
        <Table striped bordered hover>
          <thead>
            <tr>
              <th>Title</th>
              <th>Type</th>
              <th>Time</th>
              <th>Date</th>
            </tr>
          </thead>
          <tbody>
            {/* 用map循环渲染所有事件,替换硬编码的模拟数据 */}
            {this.state.events.map((event, index) => (
              <tr key={index}>
                <td>{event.title}</td>
                <td>{event.type}</td>
                <td>{event.time}</td>
                <td>{event.date}</td>
              </tr>
            ))}
          </tbody>
        </Table>
        <Container className="row"/>
        <Row className="justify-content-center">
          {/* 把添加事件的回调传给EventModal */}
          <EventModal onAddEvent={this.handleAddEvent} />
        </Row>
      </Container>
    );
  }
}

export default EventList;

步骤2:在EventModal中传递回调给EventForm

EventModal作为中间组件,需要把从EventList收到的回调再传递给内部的EventForm,同时还要传递关闭模态框的方法,让表单提交后自动关闭弹窗:

import React, { useState } from "react";
import {Button, Modal} from "react-bootstrap";
import EventForm from "./EventForm";

function EventModal({ onAddEvent }) {
  const [show, setShow] = useState(false);
  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  // 处理表单提交:先添加事件,再关闭模态框
  const handleFormSubmit = (newEvent) => {
    onAddEvent(newEvent);
    handleClose();
  };

  return (
    <>
      <Button variant="primary" onClick={handleShow}>
        Add New Event
      </Button>
      <Modal show={show} onHide={handleClose} backdrop="static" keyboard={false} >
        <Modal.Header closeButton>
          <Modal.Title>New Event</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          {/* 把表单提交回调传给EventForm */}
          <EventForm onSubmit={handleFormSubmit} />
        </Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={handleClose}>
            Close
          </Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

export default EventModal;

步骤3:完善EventForm组件,收集完整数据并触发回调

现在需要给EventForm添加日期状态管理,处理日期选择器的输入,然后在表单提交时把所有数据传递给父组件的回调:

import React from "react";
import {Button, Container, Form} from "react-bootstrap";
import CustomDatePicker from "./CustomDatePicker";

const timeSlots = [
  { id: 1, value: '11:30AM' },
  { id: 2, value: '12:00PM' },
  { id: 3, value: '12:30PM' },
  { id: 4, value: '01:00PM' },
  { id: 5, value: '01:30PM' },
  { id: 6, value: '02:00PM' },
  { id: 7, value: '02:30PM' },
  { id: 8, value: '03:00PM' },
];

const eventTypes = [
  { id: 1, value: 'Webinar', },
  { id: 2, value: 'Workshop', },
  { id: 3, value: 'Confernece', },
];

// 合并重复的选项组件,减少冗余代码
function SelectOptions({ options }) {
  return (
    options.map(option => (
      <option key={option.id} value={option.value}>
        {option.value}
      </option>)
    )
  );
}

class EventForm extends React.Component{
  constructor() {
    super();
    this.state = {
      title: '',
      eventtype: '', // 初始值设为空字符串,避免select组件警告
      time: '',
      date: '' // 添加日期状态
    }
  }

  handleTitleChange = (event) => {
    this.setState({ title: event.target.value })
  };

  handleTypeChange = (event) => {
    this.setState({ eventtype: event.target.value })
  };

  handleTimeChange = (event) => {
    this.setState({ time: event.target.value })
  };

  // 处理日期选择:假设CustomDatePicker的onChange返回格式化后的日期字符串
  handleDateChange = (selectedDate) => {
    this.setState({ date: selectedDate });
  };

  handleSubmit = (event) => {
    event.preventDefault(); // 阻止表单默认提交行为
    // 收集所有表单数据
    const newEvent = {
      title: this.state.title,
      type: this.state.eventtype,
      time: this.state.time,
      date: this.state.date
    };
    // 调用父组件传来的回调,传递新事件数据
    this.props.onSubmit(newEvent);
    // 重置表单状态
    this.setState({
      title: '',
      eventtype: '',
      time: '',
      date: ''
    });
  };

  render() {
    return (
      <Container fluid>
        <Form onSubmit={this.handleSubmit}>
          <Form.Group controlId="Title">
            <Form.Label>Title</Form.Label>
            <Form.Control 
              placeholder="Event Title" 
              name="title" 
              value={this.state.title} 
              onChange={this.handleTitleChange}
            />
          </Form.Group>
          <Form.Group controlId="EventType">
            <Form.Label>Event Type</Form.Label>
            <Form.Control 
              as="select" 
              name="eventtype" 
              value={this.state.eventtype} 
              onChange={this.handleTypeChange}
            >
              <SelectOptions options={eventTypes} />
            </Form.Control>
          </Form.Group>
          <Form.Group controlId="Slots">
            <Form.Label>Time Slots</Form.Label>
            <Form.Control 
              as="select" 
              name="time" 
              value={this.state.time} 
              onChange={this.handleTimeChange}
            >
              <SelectOptions options={timeSlots} />
            </Form.Control>
          </Form.Group>
          <Form.Group controlId="datepicker">
            <Form.Label>Date</Form.Label>
            <br/>
            {/* 传递日期变化回调给CustomDatePicker */}
            <CustomDatePicker onChange={this.handleDateChange} />
          </Form.Group>
          <Button variant="primary" type="submit">
            Submit
          </Button>
        </Form>
      </Container>
    );
  }
}

export default EventForm;

额外注意事项

  • 确保CustomDatePicker组件支持onChange属性,能返回格式化后的日期字符串(比如"Saturday, 29/08/2020");如果它返回的是Date对象,需要在handleDateChange中先将其格式化为目标格式。
  • 列表渲染时的key用了数组索引,实际项目中如果事件有唯一ID,用ID会更稳妥。
  • 合并了重复的Options和Option组件,减少代码冗余。

这样修改后,当你在表单中填写数据并提交,新事件就会自动添加到EventList的表格中啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:52:52