React + TypeScript 向子组件传带参点击处理函数报错排查
报错原因与修复方案
直接触发_onClick is not a function的核心问题
Son组件的props接收方式完全错误
React函数组件的入参是单个 props 对象,不会按位置把每个prop拆成独立形参。原代码写的(selectedOption, onClick, customSectionStyle) =>,本质是把整个props对象赋值给第一个形参selectedOption,后面两个形参onClick、customSectionStyle全程都是undefined。组件内部调用onClick('/','home')时,自然会抛出“onClick不是函数”的错误。
正确写法是在函数参数位置解构整个props对象:({ selectedOption, onClick, customSectionStyle }) =>Mother组件传递onClick的逻辑错误
原代码写的onClick={() => handleClick},实际传出去的是一个无参箭头函数,这个函数被调用时才会返回handleClick本身,根本不会执行handleClick里的setState、路由跳转逻辑,也没有把子组件传入的href、section参数透传给真正的handleClick。
其他隐藏的逻辑/类型问题
- 类型定义存在无意义的冗余与约束缺失:
- 原定义
selectedOption?: string | '':''本身是string的子集,这种写法没有实际类型约束效果,无法匹配Mother组件里定义的选中项固定取值范围 - 原定义
onClick?: (href: string, section: string) => void | void:两个返回值类型重复,直接标注为void即可 - Mother组件里的
handleClick没有给href、section参数标注TS类型,会触发隐式any的类型报错
- 原定义
- 选中态判断逻辑不一致:
原Son组件里的高亮判断和点击传入的section值不匹配:比如第一个MyComponent点击时传的section是'home',但判断高亮时却校验selectedOption === 'rooms',第二个组件点击传'settings',判断高亮时也没有对应匹配,就算前面的报错修复,选中高亮逻辑也会失效。
修复后的完整代码示例
// 抽成公共复用的选中项类型,避免两边取值写错 type SectionKey = 'rooms' | 'questions' | 'notifications' | 'home' | 'settings' // Mother 组件 const Mother = () => { const [selectedOption, setSelectedOption] = useState<SectionKey>('rooms') const customSectionStyle = 'bg-primary-500 text-white hover:bg-primary-600' // 明确补充参数类型,避免隐式any const handleClick = (href: string, section: SectionKey) => { setSelectedOption(section); router.push(href) } return( <> {/* 直接把handleClick作为函数引用传递,不需要套空箭头函数 */} <Son onClick={handleClick} selectedOption={selectedOption} customSectionStyle={customSectionStyle} /> </> ) } // Son 组件 type SonProps = { selectedOption?: SectionKey; onClick?: (href: string, section: SectionKey) => void; customSectionStyle?: string; } const Son: React.FC<SonProps> = ({ selectedOption, onClick, customSectionStyle }) => { return( <> {/* 高亮判断和点击传入的section值保持一致,调用onClick时加可选链避免空值报错 */} <MyComponent onClick={() => onClick?.('/','home')} customStyle={selectedOption === 'home' ? customSectionStyle : ''} /> <MyComponent onClick={() => onClick?.('/settings','settings')} customStyle={selectedOption === 'settings' ? customSectionStyle : ''} /> // 其余同逻辑组件省略 </> ) }
内容的提问来源于stack exchange,提问作者user3001286
相关产品推荐
相关产品推荐

