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

React函数组件中Chakra Slider报错:无法解构event.target的name属性

解决React Slider组件onChange事件解构name属性报错问题

问题描述

我正在将一个从MongoDB获取数据、包含文本和数字输入的React类组件转换为函数组件。handleInputChange函数在文本和数字输入时正常工作,但在Slider组件上触发时抛出错误:TypeError: Cannot destructure property 'name' of 'event.target' as it is undefined。相关代码如下:

const ProgrammUpdate = props => {
  const {id} = useParams();

  const initialProgrammState = {
      id: null,
      title: "",
      description: "",
      volume_left: "",
      volume_right: "",
  }

  const [currentProgramm, setCurrentProgramm] = useState(initialProgrammState);

  const {user} = ChatState();
  const toast = useToast();
  const history = useHistory();
  const [message, setMessage] = useState("");

  const bg = useColorModeValue('brand.200', 'brand.100')
  const color = useColorModeValue('gray.800', 'white')

  const getProgramm = programmId => {
      HoerprogrammDataService.get(programmId)
          .then(response => {
              setCurrentProgramm(response.data);
              console.log(response.data);
          })
          .catch(e => {
              console.log(e);
          })
  }

  useEffect(() => {
      if (id)
          getProgramm(id);
      // eslint-disable-next-line
      console.log(id)
  }, [id]);

  const handleInputChange = event => {
      const {name, value} = event.target;
      setCurrentProgramm({...currentProgramm, [name]: value});
  };

  const updateProgramm = () => {
      HoerprogrammDataService.update(id, currentProgramm)
          .then(response => {
              console.log(response.data);
              history.push('/programme');
          })
          .catch(e => {
              console.log(e);
          });
  };

  const deleteProgramm = () => {
      HoerprogrammDataService.delete(currentProgramm.id)
          .then(response => {
              console.log(response.data);
              history.push('/programme');
          })
          .catch(e => {
              console.log(e);
          });
  };

  return(
    <LandingLayout>
      <h2>Test</h2>
      {currentProgramm ? (
        <>
          <Input
              placeholder={currentProgramm.title} size='md'
              type="text"
              className="form-control"
              id="title"
              required
              value={currentProgramm.title}
              onChange={handleInputChange}
              name="title"
          />
          <Input
              placeholder={currentProgramm.volume_left}
              type="text"
              className="form-control"
              id="volume_left"
              value={currentProgramm.volume_left}
              onChange={handleInputChange}
              name="volume_left"
          />
          <Slider
              flex='1'
              value={currentProgramm.volume_left}
              onChange={handleInputChange}
              orientation='horizontal'
              minH='20'
              name="volume_left"
              min={0} max={10} step={1}
          >
              <SliderMark value={0} mt='12' ml='-1.5' fontSize='md'>0</SliderMark>
              <SliderMark value={5} mt='12' ml='-1.5' fontSize='md'>5</SliderMark>
              <SliderMark value={10} mt='12' ml='-1.5' fontSize='md'>10</SliderMark>
              <SliderTrack bg='blue.200'>
                  <SliderFilledTrack bg="blue.400" />
              </SliderTrack>
              <SliderThumb bg="blue.400" fontSize='md' boxSize='40px'>{currentProgramm.volume_left}</SliderThumb>
          </Slider>
          <Routelink to={"/programme"} className={"nav-link"}>
              <Button variant={ "outline"} colorScheme={"red"}>Abbruch</Button>
          </Routelink>
          <button className="badge badge-danger mr-2" onClick={deleteProgramm}>
              Delete
          </button>
          <button
              type="submit"
              className="badge badge-success"
              onClick={updateProgramm}
          >
              Update
          </button>
          <p>{message}</p>
        </>
      ) : (
        <Box d="flex" alignItems="center" justifyContent="center" h="100%">
            <Text fontSize="3xl" pb={3} fontFamily="Work sans">Programm nicht geladen</Text>
        </Box>
      )}
    </LandingLayout>
  )
}
export default ProgrammUpdate;

错误原因

你使用的Slider组件(推测是Chakra UI的Slider)的onChange回调参数和普通input组件不同:

  • 普通input的onChange接收标准事件对象,包含target.name和target.value属性
  • Slider的onChange直接返回当前滑块的数值,而非事件对象,因此解构event.target会触发undefined错误

解决方案

推荐使用明确传递字段名的方式重构回调函数,更易维护且避免类型判断:

1. 重构handleInputChange函数

修改函数为接收字段名和值的形式,同时处理数字类型转换:

const handleInputChange = (name, value) => {
  // 针对音量字段做数字类型转换,避免字符串与数字混合
  if (['volume_left', 'volume_right'].includes(name)) {
    value = Number(value);
  }
  setCurrentProgramm(prev => ({...prev, [name]: value}));
};

2. 更新各组件的onChange调用

  • 普通Input组件:通过事件对象提取name和值
<Input
  placeholder={currentProgramm.title} size='md'
  type="text"
  className="form-control"
  id="title"
  required
  value={currentProgramm.title}
  onChange={(e) => handleInputChange(e.target.name, e.target.value)}
  name="title"
/>

<Input
  placeholder={currentProgramm.volume_left}
  type="text"
  className="form-control"
  id="volume_left"
  value={currentProgramm.volume_left}
  onChange={(e) => handleInputChange(e.target.name, e.target.value)}
  name="volume_left"
/>
  • Slider组件:直接传递字段名和滑块返回的数值
<Slider
  flex='1'
  value={currentProgramm.volume_left}
  onChange={(value) => handleInputChange('volume_left', value)}
  orientation='horizontal'
  minH='20'
  min={0} max={10} step={1}
>
  {/* ...Slider子组件保持不变 */}
</Slider>

3. 优化初始状态(可选)

将音量字段的初始值改为数字类型,保持状态类型统一:

const initialProgrammState = {
    id: null,
    title: "",
    description: "",
    volume_left: 0,
    volume_right: 0,
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:50:17