React+TS中如何正确调用TopComponent的AddToCart函数prop
问题根因
你的代码无法生效核心是3个写法错误:
- 类组件初始
state没有给AddToCart赋初始值,首次渲染时this.state.AddToCart是undefined,子组件拿到空值根本无法调用 - 错误地把回调函数存放在
state中,要等按钮点击才通过setState给函数赋值,首次渲染阶段子组件完全拿不到加购方法;且每次点击都会生成新的函数引用,触发子组件无意义重渲染 - 类型定义和实际实现不匹配:函数签名标注返回值为
void,实际返回了字符串,参数e也没有定义具体类型,TS校验会直接报错;子组件调用prop时没有做非空校验,父组件未传值时直接调用会抛运行时错误
正确实现代码
首先修正父组件MainComponent的逻辑,不要把回调函数存在state里:
// state只存实际业务数据,不需要存回调函数 type MainState = { cartItems?: Array<{id: number; name: string}>; }; export class MainComponent extends React.Component<{}, MainState> { // 直接定义为类属性,组件初始化时就存在,引用稳定 AddToCart = (e: {id: number; name: string}) => { // 写实际加购逻辑,比如更新购物车数据 this.setState(prev => ({ cartItems: [...(prev.cartItems || []), e] })); // 确实需要返回值就和类型定义保持一致,不要标void return "someValue"; }; render() { return ( <> {/* 直接把类方法传给子组件,不需要从state里取 */} <TopComponent AddToCart={this.AddToCart} /> <button onClick={() => { // 测试触发加购直接调用方法即可,不需要重新给state塞函数 this.AddToCart({id: 1, name: "测试商品"}); }} > 父组件测试加购 </button> </> ); } }
然后修正子组件TopComponent的类型和调用逻辑,加非空校验:
type TopProps = { // 函数签名和父组件传递的保持一致,可选属性加可选标记 AddToCart?: (e: {id: number; name: string}) => string | void; }; export class TopComponent extends React.Component<TopProps> { render() { return ( <button onClick={() => { // 可选链做非空判断,父组件没传方法时不会报错 this.props.AddToCart?.({id: 2, name: "子组件商品"}); }} > 子组件加购 </button> ); } }
注意事项
- React类组件中,传给子组件的回调函数不要存放在
state里,直接定义为类属性/在构造函数中绑定this后传递即可,能保证引用稳定,减少不必要重渲染 - 可选类型的prop调用前一定要做非空校验,避免运行时报错
- TS类型定义要和实际实现完全对齐,参数、返回值类型不要错标
内容的提问来源于stack exchange,提问作者msd
相关产品推荐
相关产品推荐

