Class组件
1. 自定义事件
📄 Parent.js
import React, { Component } from 'react';
import Child from './Child';
class Parent extends Component {
componentDidMount () {
console.log(this.childRef)
}
handleChildEvent = (ref) => {
this.childRef = ref
}
handleClick = () => {
this.childRef.sendMessage()
}
render () {
return (
<>
<Child
onChildEvent={this.handleChildEvent}
/>
<button onClick={this.handleClick}>Trigger Child Event</button>
</>
);
}
}
export default Parent;
📄 Child.js
import React, { Component } from 'react';
class Child extends Component {
componentDidMount () {
this.props.onChildEvent(this)
}
sendMessage = () => {
console.log('sending message')
}
render () {
return ( <div>Child</div> );
}
}
export default Child;
2. 使用 React.createRef()
📄 Parent.js
import React, { Component } from 'react';
import Child from './Child';
class Parent extends Component {
constructor(props) {
super(props)
this.childRef = React.createRef()
}
handleClick = () => {
this.childRef.current.sendMessage()
}
render () {
return (
<>
<Child
ref={this.childRef}
/>
<button onClick={this.handleClick}>Trigger Child Event</button>
</>
);
}
}
export default Parent;
而子组件就是一个普通的组件
📄 Child.js
import React, { Component } from 'react';
class Child extends Component {
sendMessage = () => {
console.log('sending message')
}
render () {
return ( <div>Child</div> );
}
}
export default Child;
Function组件
默认情况下,不能在函数组件上使用 ref 属性,因为它们没有实例。所以上面的两种方式是行不通的。 解决办法就是使用 forwardRef 和 useImperativeHandle 。
不过在函数的内部是可以使用 useRef 钩子来获取组件内的DOM元素。
📄 Parent.js
import React, { useRef } from 'react';
import Child from './Child';
const Parent = () => {
const childRef = useRef(null)
const handleClick = () => {
childRef.current.sendMessage()
}
return (
<>
<Child
ref={childRef}
/>
<button onClick={handleClick}>Trigger Child Event</button>
</>
);
}
export default Parent;
📄 Child.js
import React, { forwardRef, useImperativeHandle } from 'react';
const Child = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
sendMessage
}))
const sendMessage = () => {
console.log('sending message')
}
return ( <div>Child</div> );
})
export default Child;
注: 上面的例子中只是简单地演示了父子组件之间的方法调用,当然实际情况中子组件中可以也会有自己的 ref 指向自己内部的 DOM 元素,不过这些原理都是一样的。
|