父组件获取子组件的 state 或方法的几种方式
在一些业务场景中,我们需要在父组件中获取子组件的 state 或者方法。在 Vue 中,可以给子组件定义一个 ref ,然后在父组件中通过 this.$refs.ref 获取子组件中的方法或属性。在 React 中,同样也可以通过 ref 的方式获取子组件的 state 或方法。
下面,我们来看看在父组件中如何获取子组件的state或方法。
以下方法获取子组件的state或方法仅适用于class组件
方法一:给子组件添加 ref 属性
首先给子组件(在父组件中调用)添加属性 ref='child'
<Child ref='child' />复制代码
然后在父组件中使用 this.refs.child 的形式获取子组件的state 或方法
clickHandle = () => { // 获取子组件的 state console.log('this is child state: ', this.refs.child.state) // 获取子组件的方法 this.refs.child.say() }复制代码
完整示例:codesandbox.io/s/get-child…
注意:string 类型的 Refs 转发已经过时,例如上面的 this.refs.child 的方式就是 string 类型的 Refs,react 可能会在未来的版本中将 string 类型的 Refs 移除,建议使用回调函数或 createRef() 的方式代替。
除了给 ref 属性赋值一个字符串,还可以给 ref 赋值一个回调函数:
给子组件添加 ref={(ref) => (this.child = ref)}
<Child ref={(ref) => (this.child = ref)} />复制代码
然后在父组件中使用 this.child.state 或 this.child.methoName 获取子组件的state 或方法:
clickHandle = () => { console.log("this is child state: ", this.child.state); this.child.say(); };复制代码
完整示例:codesandbox.io/s/get-child…
方法二:给子组件添加 onRef 属性
此种方式实际上是通过 props + 回调 的方式获取到子组件的this实例
首先给子组件添加 onRef={(ref) => this.child = ref },获取子组件暴露出来的 this 对象:
<Child onRef={(ref) => this.child = ref } />复制代码
onRef 回调函数中的 ref 参数就是子组件暴露出来的子组件的 this 对象,将子组件的 this 对象赋值给父组件的 child 属性上。
然后在子组件中的 constructor 构造函数中将子组件的 this 对象暴露给父组件:
constructor(props: any) { super(props) if (this.props.onRef) this.props.onRef(this) }复制代码
或者也可以在子组件的 componentDidMount 生命周期函数中将子组件的 this 对象暴露给父组件:
componentDidMount() { if (this.props.onRef) { this.props.onRef(this); } }复制代码
然后在父组件中使用 this.child.xxx 的方式获取子组件的 state 或方法
clickHandle = () => { console.log("this is child state: ", this.child.state); this.child.say(); };复制代码
完整示例:codesandbox.io/s/get-child…
方法三:使用 createRef() 创建 ref 容器
首先在父组件中创建 ref 容器:
childRef: any = React.createRef();复制代码
然后给子组件添加 ref 属性:ref={this.childRef}
<Child ref={this.childRef}/>复制代码
然后就可以在父组件中使用 this.childRef.current 获取到子组件的 state 或 方法了:
clickHandle = () => { console.log("this is child state: ", this.childRef.current.state); this.childRef.current.say(); };
作者:紫圣
链接:https://juejin.cn/post/7033162335296585736