MERN栈React Redux如何传递预约ID到提交函数并正确派发action
问题根因
- 参数传递错误:
handleSubmit定义要求第一个参数为事件对象e、第二个为预约ID,但按钮点击回调仅传入了预约ID,导致执行e.preventDefault()时直接抛出 undefined 报错,逻辑中断 - 表单状态全局共享:所有预约条目共用同一个
reasonForMassage状态,修改任意一条的输入内容会同步覆盖所有条目的值,无法拿到当前提交预约对应的表单数据 - 表单字段收集不全:同意按摩区域复选框、禁忌按摩区域输入值未做状态管理,提交时这些数据会丢失
- 表单默认行为未处理:提交按钮默认是
submit类型,未显式指定类型时可能触发原生表单提交,导致页面刷新
修复后的完整代码
import React, { useState } from 'react' import { useDispatch } from 'react-redux' import { confirmAppointment } from '../../../actions/appointment' const ConfirmAppointment = ({user}) => { const dispatch = useDispatch() // 重命名用户ID为userId,避免和预约ID混淆 const { appointments, _id: userId } = user?.result ?? {} const today = new Date() // 按预约ID存储对应表单数据,隔离各条目的状态 const [formState, setFormState] = useState({}) // 普通输入框值更新逻辑 const handleFieldChange = (appointmentId, field, value) => { setFormState(prev => ({ ...prev, [appointmentId]: { ...prev[appointmentId], [field]: value } })) } // 复选框值更新逻辑 const handleCheckboxChange = (appointmentId, area, checked) => { setFormState(prev => ({ ...prev, [appointmentId]: { ...prev[appointmentId], consentAreas: { ...prev[appointmentId]?.consentAreas, [area]: checked } } })) } const handleSubmit = (e, appointmentId) => { e.preventDefault() const currentFormData = formState[appointmentId] ?? {} console.log(appointmentId, currentFormData) dispatch(confirmAppointment(userId, appointmentId, currentFormData)) } if (!appointments?.length) { return <div>No upcoming appointments</div> } return ( <div style={{marginTop: '3em'}}> <h4>Upcoming Appointments</h4> {appointments.map((appointment) => { // 过期预约直接跳过渲染 if (new Date(appointment?.date) < today) return null const currentForm = formState[appointment._id] ?? {} return ( <div style={{marginBottom: '3em'}} key={appointment._id} > <table className="ui table"> <thead> <tr> <th>Date</th> <th>Time</th> <th>Duration</th> </tr> </thead> <tbody> <tr> <td>{appointment?.date}</td> <td>{appointment?.time}</td> <td>{appointment?.duration}</td> </tr> </tbody> </table> <form className="ui form"> <div className="ui fields"> <div className="ui field"> <label>Reason for booking massage:</label> <input type="text" value={currentForm.reasonForMassage ?? ''} onChange={(e)=>handleFieldChange(appointment._id, 'reasonForMassage', e.target.value)} /> </div> <div className="ui field"> <h5>I give consent to massage the following areas:</h5> <div> <input type="checkbox" checked={currentForm.consentAreas?.glutes ?? false} onChange={(e) => handleCheckboxChange(appointment._id, 'glutes', e.target.checked)} /> <label>Glutes</label> <input type="checkbox" checked={currentForm.consentAreas?.abdomen ?? false} onChange={(e) => handleCheckboxChange(appointment._id, 'abdomen', e.target.checked)} /> <label>Abdomen</label> <input type="checkbox" checked={currentForm.consentAreas?.chest ?? false} onChange={(e) => handleCheckboxChange(appointment._id, 'chest', e.target.checked)} /> <label>Chest</label> <input type="checkbox" checked={currentForm.consentAreas?.innerThighs ?? false} onChange={(e) => handleCheckboxChange(appointment._id, 'innerThighs', e.target.checked)} /> <label>Inner thighs</label> </div> </div> <div className="ui field"> <label>Are there any other areas you would not like to be massaged?</label> <input type="text" value={currentForm.forbiddenAreas ?? ''} onChange={(e) => handleFieldChange(appointment._id, 'forbiddenAreas', e.target.value)} /> </div> </div> <button type="button" onClick={(e)=>handleSubmit(e, appointment._id)} className="ui button" > Confirm Appointment </button> </form> </div> ) })} </div> ) } export default ConfirmAppointment
内容的提问来源于stack exchange,提问作者Cip
相关产品推荐
相关产品推荐

