ReactJS中点击父类组件按钮时如何获取子函数组件的方法
你当前代码存在的核心问题
- 你声明Increment是函数组件,但实际代码写的是类组件,且子组件内部没有定义count状态,直接调用setState修改count无效,因为count状态是定义在父组件Timer中的
- onClick事件需要接收回调函数,你直接把
<Increment />组件实例写在onClick配置项中,完全无法触发执行逻辑 - 要在父组件调用子组件的方法,需要通过ref获取子组件实例,直接引入组件不做ref绑定是拿不到子组件内部方法的
方案1:符合你需求的「父组件点击触发子组件方法」实现(用ref)
修正后的父组件代码
import React from "react"; import Increment from "./Increment"; class Timer extends React.Component { // 定义子组件ref childRef = React.createRef(); state = { count: 0 } handleClick = () => { // 通过ref调用子组件的incrementTimer方法 this.childRef.current.incrementTimer(this.state.count, (newCount) => { this.setState({ count: newCount }) }) } render() { return ( <div className="top"> <span className="display">{this.state.count}</span> <button className="btn btn-primary" onClick={this.handleClick} > + </button> {/* 绑定ref到子组件 */} <Increment ref={this.childRef} /> </div> ) } } export default Timer
修正后的类子组件代码
import React, { Component } from "react"; class Increment extends Component { incrementTimer = (currentCount, updateParentCount) => { const newCount = currentCount + 1; // 调用父组件传过来的回调更新父组件状态 updateParentCount(newCount); } render() { // 子组件如果不需要渲染UI可以返回null return null; } } export default Increment
如果你要改成函数子组件,需要用forwardRef配合useImperativeHandle暴露方法
import React, { forwardRef, useImperativeHandle } from "react"; // 用forwardRef包裹组件接收ref const Increment = forwardRef((props, ref) => { // 暴露方法给父组件 useImperativeHandle(ref, () => ({ incrementTimer: (currentCount, updateParentCount) => { const newCount = currentCount + 1; updateParentCount(newCount); } })) return null; }) export default Increment
方案2:更符合React单向数据流的常规实现(不需要调用子组件方法)
如果你的子组件只是封装加1逻辑,完全不需要跨组件调用方法,直接把更新逻辑写在父组件即可,代码更简洁:
import React from "react"; class Timer extends React.Component { state = { count: 0 } increment = () => { this.setState(prev => ({ count: prev.count + 1 })) } render() { return ( <div className="top"> <span className="display">{this.state.count}</span> <button className="btn btn-primary" onClick={this.increment} > + </button> </div> ) } } export default Timer
内容的提问来源于stack exchange,提问作者mrhrifat
相关产品推荐
相关产品推荐

