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

React.js中Modal提交后所有列表项状态都变更而非仅选中项如何解决

问题根因

你当前的代码存在两个核心问题导致所有时间段同步修改:

  • 所有时间段共用全局唯一的name和phoneNumber状态,只要这两个值更新,所有引用这两个状态的时间段节点都会同步渲染最新值
  • 点击时间段打开模态框时,没有记录当前选中的是哪个时间段,提交表单时无法定位到要修改的目标时间段,只能修改全局共用的状态

修复方案

改造思路

  1. 替换单一的用户信息状态为时间段数组,每个时间段独立存储自己的预约信息
  2. 新增状态记录当前激活的时间段ID,点击打开模态框时赋值
  3. 表单提交时只更新激活ID对应的时间段数据,不修改全局共用变量
  4. 遍历时间段数组渲染列表,避免重复写死节点代码

修复后完整代码

import React, {useState} from 'react'
import './App.css';
import Modal from 'react-modal';

Modal.setAppElement('#root')

function App() {
  const [modalIsOpen, setModalIsOpen] = useState(false);
  // 时间段数组,每个项独立存储对应时段的预约信息
  const [timeSlots, setTimeSlots] = useState([
    {id: 1, time: '9:00am', name: '', phoneNumber: ''},
    {id: 2, time: '10:00am', name: '', phoneNumber: ''}
  ]);
  // 记录当前选中的时间段ID
  const [activeSlotId, setActiveSlotId] = useState(null);
  // 表单临时状态,仅用于模态框输入暂存
  const [formName, setFormName] = useState("");
  const [formPhone, setFormPhone] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    // 仅更新选中ID对应的时间段数据
    setTimeSlots(prevSlots => prevSlots.map(slot => {
      if (slot.id === activeSlotId) {
        return {...slot, name: formName, phoneNumber: formPhone}
      }
      return slot
    }))
    // 提交后重置状态
    setModalIsOpen(false);
    setFormName("");
    setFormPhone("");
  }

  return (
    <div className="App">
      <h2>Hello world</h2>
    
      <Modal isOpen={modalIsOpen} onRequestClose={() => setModalIsOpen(false)}>
        <form onSubmit={handleSubmit}>
          <input 
            type="text" 
            required 
            name="name" 
            placeholder="enter full name" 
            value={formName} 
            onChange={(e)=> setFormName(e.target.value)}  
          />
          <input 
            type="number" 
            name="phoneNumber" 
            required 
            maxLength="10" 
            value={formPhone} 
            placeholder="enter phone number" 
            onChange={(e)=> setFormPhone(e.target.value)} 
          />
          <button type="submit">Confirm</button>
        </form>
      </Modal>
      

      <div className="time-slot-list">
        <ul>
          {/* 遍历数组渲染所有时间段,后续新增时段只需修改timeSlots数组即可 */}
          {timeSlots.map(slot => (
            <li 
              key={slot.id}
              className={`time-slot ${slot.name ? 'redBg' : ''}`}
              onClick={() => {
                setActiveSlotId(slot.id)
                // 已预约的时段打开模态框时自动回填数据
                setFormName(slot.name)
                setFormPhone(slot.phoneNumber)
                setModalIsOpen(true)
              }}
            >
              {slot.time}
              {slot.name && <p>{slot.name}</p>}
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 11:27:03