React onClick事件中event.target.id为undefined的报错求助
问题:React onClick处理函数中event.target.id返回undefined并报错
在React组件的onClick处理函数中尝试读取event.target.id时返回undefined,出现如下报错:
react-dom.development.js:327 Uncaught TypeError: Cannot read properties of undefined (reading 'id') at clickHandler
相关代码:
const clickHandler = (event) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars let buttonID = event.target.id; console.log("button ID is ", buttonID); if(buttonID === "cancelButton"){ console.log("it is cancel button here"); } else { console.log("it is not cancel button here"); } setVisible(false); event.preventDefault(); } export const something: FunctionComponent<somethingProps> = (props) => { return( <Modal onDismiss={() => setVisible(false)} visible={visible} closeAriaLabel="Close modal" size="small" footer={ <Box float="right"> <SpaceBetween direction="horizontal" size="xs"> <Button variant="link" onClick={clickHandler} id="cancelButton">Cancel</Button> <Button variant="primary" onClick={clickHandler} id="okButton">Confirm</Button> </SpaceBetween> </Box> } header={`Would you like to publish timeline?`} > <span> <p> Publishing timeline for this launch will send out approval request to GM. </p> </span> </Modal> ) };
原因分析
event.target指向实际触发事件的DOM元素,若Button组件内部包含子元素(如文本节点、图标等),点击时触发事件的是这些子元素,而非Button本身,子元素没有设置id,因此event.target.id返回undefined。- 调用
setVisible(false)后组件可能立即卸载/重渲染,React合成事件对象会被回收,后续访问event.target会触发报错。
解决方案
方案1:使用event.currentTarget替代event.target
event.currentTarget始终指向注册事件的元素(即Button组件本身),不受子元素触发事件的影响:
const clickHandler = (event) => { let buttonID = event.currentTarget.id; console.log("button ID is ", buttonID); if(buttonID === "cancelButton"){ console.log("it is cancel button here"); } else { console.log("it is not cancel button here"); } setVisible(false); event.preventDefault(); }
方案2:直接传递id到处理函数
无需依赖event对象,绑定事件时直接传入id参数:
const clickHandler = (buttonID) => { console.log("button ID is ", buttonID); if(buttonID === "cancelButton"){ console.log("it is cancel button here"); } else { console.log("it is not cancel button here"); } setVisible(false); } // 组件内的Button调用方式 <Button variant="link" onClick={() => clickHandler("cancelButton")} id="cancelButton">Cancel</Button> <Button variant="primary" onClick={() => clickHandler("okButton")} id="okButton">Confirm</Button>
方案3:提前获取属性再更新状态
若必须使用event.target,先读取所需属性再执行状态更新,避免事件对象被回收:
const clickHandler = (event) => { let buttonID = event.target.id; console.log("button ID is ", buttonID); if(buttonID === "cancelButton"){ console.log("it is cancel button here"); } else { console.log("it is not cancel button here"); } event.preventDefault(); // 最后执行状态更新 setVisible(false); }
内容的提问来源于stack exchange,提问作者ptratyou
相关产品推荐
相关产品推荐

