React Redux项目子组件向父组件传参时counter未定义问题排查
我来帮你分析下问题所在,以及怎么修复:
为什么会报counter is not defined?
在你的父组件Products的render方法里,给GridLayout传递addProductToBasket回调时,你写了:
addProductToBasket={() => this.addProductToBasket(product, counter)}
这里的counter在父组件的当前作用域里完全不存在——counter是子组件GridLayout的内部state,父组件在渲染列表的时候根本访问不到这个变量,所以浏览器会直接抛出未定义的错误。
更关键的是,你其实已经在子组件的handleAdd方法里正确处理了counter的传递:子组件更新state后,会调用this.props.addProductToBasket(product, counter)把最新的counter传过去,所以父组件根本不需要在传递回调时提前指定counter。
怎么修复?
只需要修改父组件中传递addProductToBasket的方式,去掉那个不存在的counter引用即可,有两种常见的写法:
写法一:传递带参数的箭头函数
直接让箭头函数接收子组件传过来的product和counter,再转发给父组件的方法:
<GridLayout key={i} name={product.name} id={product.id} description={product.description} price={product.price} addProductToBasket={(product, counter) => this.addProductToBasket(product, counter)} />
写法二:直接传递方法引用(更简洁)
可以把整个product对象作为props传给子组件,然后直接传递父组件的addProductToBasket方法引用:
// 父组件render里的GridLayout <GridLayout key={i} product={product} // 新增:传递整个product对象 name={product.name} id={product.id} description={product.description} price={product.price} addProductToBasket={this.addProductToBasket} />
然后修改子组件的handleAdd方法,直接使用this.props.product:
handleAdd() { // 推荐用函数式更新state,保证拿到最新的state值 this.setState(prevState => ({ counter: prevState.counter + 1 }), () => { const counter = this.state.counter; console.log('counter is' + counter); this.props.addProductToBasket(this.props.product, counter); }); }
额外小建议
在更新依赖之前state的状态时(比如counter +=1),尽量使用函数式的setState(也就是setState(prevState => newState)),因为setState是异步操作,函数式更新能确保你基于最新的state值进行修改,避免出现状态不同步的bug。
内容的提问来源于stack exchange,提问作者user74843

