React向子组件传递父组件状态更新函数后调用无响应如何解决
问题原因
- props传递链路断裂:你在Login组件中仅将
updateTurn方法传给了<Pledge>路由组件,但调用this.props.updateTurn的是Game组件,Game组件没有拿到对应的prop,调用时实际执行的是undefined,自然不会触发console.log输出。 - 嵌套组件事件冲突:你将绑定了onClick事件的button放在了
<Link>组件内部,点击按钮时会优先触发Link的页面跳转逻辑,回调函数还没执行就已经发生页面跳转,导致回调被中断。 - 类方法this绑定丢失:Login组件中的
updateTurn是普通类方法,未绑定this指向,就算正确传递到子组件,执行时this指向会发生偏移,执行this.setState时会抛出错误(当前阶段尚未触发该报错,因为函数本身还没被成功调用)。
解决方案
1. 补全props传递链路
如果Game是Pledge的子组件,需要在Pledge组件的render方法中将收到的updateTurn继续传给Game:
// Pledge组件render内部代码 <Game updateTurn={this.props.updateTurn} />
如果Game是独立的路由组件,直接在Login的对应Route上传递prop:
<Route path="/play/game"> <Game data={this.state.data} updateTurn={this.updateTurn}/> </Route>
2. 修复事件冲突,改用编程式导航
不要嵌套Link和带点击事件的按钮,把跳转逻辑放到点击回调内执行。先使用react-router的withRouter高阶组件包裹Game组件拿到history属性,再修改按钮逻辑:
// Game组件修改后的按钮部分 <button className="button" onClick={() => { this.props.updateTurn(); this.props.history.push(Launcher.getRandomGame()); }} > Next </button>
3. 绑定updateTurn的this指向
三种方案任选其一即可:
- 方案1:在Login组件的constructor中绑定this
constructor(props) { super(props); // 其他state初始化逻辑 this.updateTurn = this.updateTurn.bind(this); }
- 方案2:传递prop时用箭头函数包裹
<Pledge data={this.state.data} updateTurn={() => this.updateTurn()}/>
- 方案3:将updateTurn改为类属性箭头函数
updateTurn = () => { console.log("UPDATE") this.setState(prevState => { // 你的状态更新逻辑 }); }
内容的提问来源于stack exchange,提问作者choco02
相关产品推荐
相关产品推荐

