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
相关产品推荐
相关产品推荐

