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

ReactJS:表单提交时如何渲染同级的EmployeeTable组件?

解决方案:状态提升实现表单提交更新右侧表格

要实现提交表单后用新数据更新右侧的EmployeeTable组件,核心是状态提升——把员工列表的状态放在父组件中,让表单组件和表格组件共享这个状态。表单负责收集数据并通知父组件更新列表,表格组件根据父组件传入的列表数据渲染,这样列表更新时表格会自动重新渲染。

步骤1:创建父组件(如App.jsx)

将员工列表的状态维护在父组件,同时提供添加新员工的方法,分别传递给表单和表格组件。

import { useState } from "react";
import EmpFormComponent from "./EmpForm";
import EmployeeTableComponent from "./EmpTable";

function App() {
  // 初始化员工列表,包含原有示例数据
  const [employees, setEmployees] = useState([
    {
      id: 1,
      firstname: "Smith",
      lastname: "Mathew",
      joindate: "09/Jan/2021",
      department: "Development",
      technologies: [
        { id: 1, domain: "Java Spring Boot" },
        { id: 4, domain: " Asp.Net MVC" },
      ],
      projects: 3,
    },
    {
      id: 2,
      firstname: "Maria",
      lastname: "Garcia",
      joindate: "09/Oct/2019",
      department: "Development",
      technologies: [
        { id: 1, domain: "Java Spring Boot" },
        { id: 2, domain: "Python Django" },
      ],
      projects: 8,
    },
    {
      id: 3,
      firstname: "Jacob",
      lastname: "Abraham",
      joindate: "21/Mar/2021",
      department: "Testing",
      technologies: [{ id: 3, domain: "Express Js" }],
      projects: 1,
    },
    {
      id: 4,
      firstname: "Jessica",
      lastname: "Antoine",
      joindate: "18/Aug/2021",
      department: "Development",
      technologies: [
        { id: 1, domain: "Java Spring Boot" },
        { id: 4, domain: "Asp.Net MVC" },
      ],
      projects: 11,
    },
  ]);

  // 添加新员工的方法,处理数据格式转换
  const addNewEmployee = (newEmp) => {
    // 将表单的日期格式转换为表格需要的格式(如DD/MMM/YYYY)
    const formattedDate = new Date(newEmp.userDate).toLocaleDateString("en-GB", {
      day: "2-digit",
      month: "short",
      year: "numeric",
    }).replace(/ /g, "/");

    // 转换technologies为表格需要的结构
    const formattedTechnologies = newEmp.userTechnology.map((tech, index) => ({
      id: index + 1,
      domain: tech,
    }));

    // 构造符合表格结构的新员工对象
    const employeeToAdd = {
      id: parseInt(newEmp.userId),
      firstname: newEmp.userFirstName,
      lastname: newEmp.userLastName,
      joindate: formattedDate,
      department: newEmp.userDepartment,
      technologies: formattedTechnologies,
      projects: parseInt(newEmp.userCount),
    };

    // 更新员工列表
    setEmployees([...employees, employeeToAdd]);
  };

  return (
    <div className="container-fluid">
      <div className="row">
        {/* 左侧表单 */}
        <div className="col-md-6">
          <EmpFormComponent onAddEmployee={addNewEmployee} />
        </div>
        {/* 右侧表格 */}
        <div className="col-md-6">
          <div className="card">
            <div className="card-header">
              <h3>Employee List</h3>
            </div>
            <div className="card-body">
              <EmployeeTableComponent employees={employees} />
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;

步骤2:修改EmpForm.jsx

移除内部的submit状态和表格渲染逻辑,改为调用父组件传递的onAddEmployee方法,并重置表单数据。

import { useState } from "react";
import DepartmentComponent from "./Department";
import TechnologyComponent from "./Technology";

let EmpFormComponent = ({ onAddEmployee }) => {
  const [newEmployee, setNewEmployee] = useState({
    userId: "",
    userFirstName: "",
    userLastName: "",
    userDate: "",
    userDepartment: "",
    userTechnology: [],
    userCount: "",
  });

  const updateChange = (e) => {
    if (e.target.name !== "userTechnology") {
      setNewEmployee({ ...newEmployee, [e.target.name]: e.target.value });
    } else {
      // 更新userTechnology数组
      if (!newEmployee.userTechnology.includes(e.target.value)) {
        setNewEmployee({
          ...newEmployee,
          [e.target.name]: [...newEmployee.userTechnology, e.target.value],
        });
      } else {
        let filterUserTech = newEmployee.userTechnology.filter((item) => {
          return item !== e.target.value;
        });
        setNewEmployee({ ...newEmployee, [e.target.name]: filterUserTech });
      }
    }
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    // 调用父组件的添加方法
    onAddEmployee(newEmployee);
    // 重置表单
    setNewEmployee({
      userId: "",
      userFirstName: "",
      userLastName: "",
      userDate: "",
      userDepartment: "",
      userTechnology: [],
      userCount: "",
    });
  };

  return (
    <div className="card ms-2">
      <div className="card-header">
        <h3>Employee Form</h3>
      </div>
      <form onSubmit={handleSubmit}>
        <div className="card-body">
          <div className="row g-1 my-1">
            <div className="col-md-2">
              <input
                type="text"
                className="form-control text-center"
                placeholder="id"
                name="userId"
                value={newEmployee.userId}
                onChange={updateChange}
              />
            </div>
            <div className="col-md-5">
              <input
                type="text"
                className="form-control text-center"
                placeholder="first name"
                name="userFirstName"
                value={newEmployee.userFirstName}
                onChange={updateChange}
              />
            </div>
            <div className="col-md-5">
              <input
                type="text"
                className="form-control text-center"
                placeholder="last name"
                name="userLastName"
                value={newEmployee.userLastName}
                onChange={updateChange}
              />
            </div>
          </div>
          <div className="row g-1 my-1">
            <div className="col-md-6">
              <input
                type="date"
                className="form-control"
                name="userDate"
                value={newEmployee.userDate}
                onChange={updateChange}
              />
            </div>
            <div className="col-md-6">
              <DepartmentComponent updateChange={updateChange} />
            </div>
          </div>
          <div className="row g-1 my-1">
            <div className="col-md-12">
              <p className="my-1 text-center">Select Technology</p>
              <TechnologyComponent updateChange={updateChange} />
            </div>
          </div>
          <div className="row g-1 my-1">
            <div className="col-md-6">
              <p className="my-1 ms-1">Count of Completed Projects</p>
            </div>
            <div className="col-md-6">
              <input
                type="text"
                className="form-control text-center"
                placeholder="count"
                name="userCount"
                value={newEmployee.userCount}
                onChange={updateChange}
              />
            </div>
          </div>
          <div className="row g-1 my-1">
            <div className="col-md-12">
              <button
                className="btn btn-outline-primary float-end"
                type="submit"
              >
                Submit
              </button>
            </div>
          </div>
        </div>
      </form>
    </div>
  );
};
export default EmpFormComponent;

步骤3:修改EmpTable.jsx

移除内部的employees数组,改为接收父组件传递的employees props,同时调整依赖项,监听employees变化。

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEye } from "@fortawesome/free-solid-svg-icons";
import EmpDetails from "./EmpDetails";
import { useState, useEffect } from "react";

let EmployeeTableComponent = ({ employees }) => {
  const [hideThisDetail, setHideThisDetail] = useState();

  const toggleUnhide = (key) => {
    setHideThisDetail(key);
  };

  useEffect(() => {
    console.log("员工列表已更新:", employees);
  }, [employees]);

  return (
    <table className="table table-hover" id="myTable">
      <thead>
        <tr>
          <th>Id</th>
          <th>Employee</th>
          <th>Join Date</th>
          <th>Projects</th>
          <th>#</th>
        </tr>
      </thead>
      <tbody>
        {employees.map((item, key) => (
          <tr key={item.id}>
            <td>{item.id}</td>
            <td>
              {item.firstname}&nbsp;{item.lastname}
            </td>
            <td>{item.joindate}</td>
            <td>{item.projects}</td>
            <td>
              <button
                onClick={() => toggleUnhide(key)}
                className="btn btn-link p-0"
              >
                <FontAwesomeIcon icon={faEye} color="#1c8ee3" />
              </button>
              {key === hideThisDetail && (
                <EmpDetails
                  key={item.id}
                  department={item.department}
                  technologies={item.technologies}
                />
              )}
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  );
};

export default EmployeeTableComponent;

关键说明

  • 状态提升:将员工列表状态放在父组件,确保表单和表格共享同一数据源,避免状态分散导致的不同步问题。
  • 数据格式适配:表单提交的新员工数据需要转换为表格组件期望的结构(如日期格式、technologies数组结构),保证渲染一致性。
  • 表单重置:提交后清空表单,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:15:36