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

React+Material UI表单Date/Time组件无法获取name值报错求助

问题排查:Material UI Date/TimePicker 无法获取name值导致表单提交错误

问题描述

使用React+Material UI构建表单时,添加DatePicker和TimePicker组件后,提交表单出现错误:TypeError: Cannot read properties of undefined (reading 'name'),仅日期和时间字段存在该问题。

错误原因

  1. 回调参数不兼容:Material UI的DatePicker/TimePicker的onChange回调直接返回选中的日期/时间值(Dayjs实例),而非标准DOM事件对象,因此原有handleReservationChange函数中访问event.target.name会触发undefined报错。
  2. 无效属性传递:给LocalizationProvider添加name属性无意义,该组件不会将name传递给内部输入控件。

解决方案

1. 修改事件处理函数,兼容两种输入类型

调整handleReservationChange,使其同时支持普通输入框的DOM事件和Date/TimePicker的数值回调:

function handleReservationChange(field, value) {
  // 处理普通输入框的DOM事件
  if (typeof field === 'object' && field.target) {
    const { name, value: inputValue } = field.target;
    setReservationData(prev => ({ ...prev, [name]: inputValue }));
  } else {
    // 处理Date/TimePicker的数值(转换为ISO字符串方便后端处理)
    const formattedValue = value ? value.toISOString() : '';
    setReservationData(prev => ({ ...prev, [field]: formattedValue }));
  }
}

2. 调整DatePicker/TimePicker的onChange绑定

给Date/TimePicker明确传递字段名,替换原有的onChange={handleReservationChange}:

// DatePicker部分
<FormControl>
  <LocalizationProvider dateAdapter={AdapterDayjs} fullWidth>
    <DatePicker
      label="Date"
      value={reservationData.date}
      onChange={(value) => handleReservationChange('date', value)}
      renderInput={(params) => <TextField {...params} name="date" />}
    />
  </LocalizationProvider>
</FormControl>

// TimePicker部分
<FormControl>
  <LocalizationProvider dateAdapter={AdapterDayjs}>
    <TimePicker
      label="Time"
      value={reservationData.time}
      onChange={(value) => handleReservationChange('time', value)}
      renderInput={(params) => <TextField {...params} name="time" />}
    />
  </LocalizationProvider>
</FormControl>

3. 可选:提交时统一处理日期格式

如果不想在事件处理中转换格式,也可以在提交表单时统一将Dayjs对象转为字符串:

function handleReservationSubmit(event){
  event.preventDefault();
  const newReservation={
    ...reservationData,
    // 转换Dayjs对象为ISO字符串
    date: reservationData.date ? reservationData.date.toISOString() : '',
    time: reservationData.time ? reservationData.time.toISOString() : '',
    restaurant_id: params.id,
    user_id: user.id,
  };
  // 后续fetch逻辑不变
}

完整修改后的代码片段

function ReservationForm(){
    const navigate = useNavigate();
    const params = useParams();
    const {user}=useContext(Cont)

    const[reservationData,setReservationData]=useState({
        name:"",
        date:"",
        time:"",
        num:"",
        contact:"",
        occasion:"",
    });

    // 修改后的事件处理函数
    function handleReservationChange(field, value) {
        if (typeof field === 'object' && field.target) {
            const { name, value: inputValue } = field.target;
            setReservationData(prev => ({ ...prev, [name]: inputValue }));
        } else {
            const formattedValue = value ? value.toISOString() : '';
            setReservationData(prev => ({ ...prev, [field]: formattedValue }));
        }
    }
    
    function handleReservationSubmit(event){
        event.preventDefault();
        const newReservation={
            ...reservationData,
            restaurant_id: params.id,
            user_id: user.id,
        };

        fetch(`/reservations`, {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify(newReservation),
          })
            .then((r) => r.json())
            .then(() => {
                setReservationData({
                    name:"",
                    date:"",
                    time:"",
                    num:"",
                    contact:"",
                    occasion:"",
                })
            });
          navigate("/myreservations");
        }

    
    return(
        <>
          <Box
        component="form"
        sx={{
          "& > :not(style)": { m: 1 },
        }}
        noValidate
        autoComplete="off"
        onSubmit={handleReservationSubmit}
      >
       <h1 className="editheadings">Reserve 🍽️</h1> 
      
       <FormControl  className="inputstyle">
          <InputLabel htmlFor="component-outlined">Name</InputLabel>
          <OutlinedInput
            type="text"
            name="name" 
            id="name"
            value={reservationData.name} 
            onChange={handleReservationChange} 
            label="Name"
          />
        </FormControl>
        <br />
        {/* 修改后的DatePicker */}
        <FormControl>
          <LocalizationProvider dateAdapter={AdapterDayjs} fullWidth>
            <DatePicker
              label="Date"
              value={reservationData.date}
              onChange={(value) => handleReservationChange('date', value)}
              renderInput={(params) => <TextField {...params} name="date" />}
            />
          </LocalizationProvider>
        </FormControl>
        {/* 修改后的TimePicker */}
        <FormControl>
          <LocalizationProvider dateAdapter={AdapterDayjs}>
            <TimePicker
              label="Time"
              value={reservationData.time} 
              onChange={(value) => handleReservationChange('time', value)}
              renderInput={(params) => <TextField {...params} name="time" />}
            />
          </LocalizationProvider>
        </FormControl>
        <br />
        <FormControl className="inputstyle">
          <InputLabel htmlFor="component-outlined">No. of Guests</InputLabel>
          <OutlinedInput
            type="number"
            name="num"
            value={reservationData.num} onChange={handleReservationChange}
          />
        </FormControl>
        <br />
        <FormControl className="inputstyle">
          <InputLabel htmlFor="component-outlined">Contact</InputLabel>
          <OutlinedInput
            type="tel"
            name="contact"
            value={reservationData.contact} onChange={handleReservationChange}
            placeholder="contact"
          />
        </FormControl>
        <br />
        <FormControl className="inputstyle">
          <InputLabel htmlFor="component-outlined">Occasion</InputLabel>
          <OutlinedInput
            type="text"
            name="occasion"
            value={reservationData.occasion} onChange={handleReservationChange}
          />
        </FormControl>
        <Stack paddingLeft={15} direction="row" id="loginbutton">
          <ColorButton variant="contained" type="submit">
            {" "}
            Update Reservation
          </ColorButton>
        </Stack>
       </Box>
        </>
    )
}
export default ReservationForm;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:55:18