React 父子组件通信
可以使用useRef钩子,在父组件声明ref并绑定到子组件,子组件使用useImperativeHandle钩子暴露出状态和方法供父组件调用
函数式组件
父:
function Parent() {
// Create the child instance with useRef hook
const child = useRef()
const handleOnClick = () => {
if (child.current) {
child.current.foo()
}
}
return (
<>
<Child ref={child} />
<button onClick={handleOnClick}>Call foo</button>
</>
)
}
子:
const Child: React.FC<ChildProps> = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
foo() {
alert("Hello world")
},
}))
return <div>Child content</div>
})
类式组件
父:
class Parent extends React.Component {
constructor(props) {
super(props)
// Create the child instance using react createRef
this.child = React.createRef()
}
handleClick = () => {
// Call the child method foo
this.child.current.foo()
}
render() {
return (
<>
<Child ref={this.child} />
<button onClick={this.handleClick}>
Call foo
</button>
</>
)
}
子:
class Child extends React.Component {
// The child method foo
foo() {
alert("Hello world")
}
render() {
return <div>Child content</div>
}
}
总结
可以看出,函数式组件在使用ref时无论是写法上还是构造上都更加精巧简洁。使用 useImperativeHandle钩子可以声明出子组件所想要暴露出去的状态,更加安全可控,不至于将所有状态和方法都暴露出去。