# React 父组件调用子组件的方法
3 min read
Table of Contents
在 React 中,父组件调用父组件的方法,一般用 props 回调即可。但是如果需要在父组件中调用子组件的方法?
其实核心思想就是通过 ref 来获取子组件的实例/方法。
类组件
类组件可以通过 ref 获取子组件的实例,从而调用实例的方法。
class Sub extends React.Component { func = () => { console.log('sub function') } render() { return <div>Hello from Sub</div> }}
class App extends React.Component { constructor(props) { super(props) this.ref = React.createRef() } handleBtnClick = () => { this.ref.current.func() } render() { return ( <div className="App"> <Sub ref={this.ref} /> <button onClick={this.handleBtnClick}>Click Me</button> </div> ) }}代码示例:codesandbox
函数组件
函数组件对于 ref 的处理,需要使用 forwardRef 来进行 ref 的转发。使用 forwardRef 需要指定 ref 的指向。
import { forwardRef } from 'react'
const MyInput = forwardRef(function MyInput(props, ref) { const { label, ...otherProps } = props return ( <label> {label} <input {...otherProps} ref={ref} /> </label> )})上面是最常用的 ref 使用方式,指向一个 DOM 节点,可以获取 DOM 实例。但是这样子无法获取子组件的方法。
好在 React 提供了导出内部方法的钩子 useImperativeHandle
const MyInput = forwardRef(function MyInput(props, ref) { const inputRef = useRef(null)
useImperativeHandle(ref, () => { return { focus() { inputRef.current.focus() }, scrollIntoView() { inputRef.current.scrollIntoView() }, } }, [])
return <input {...props} ref={inputRef} />})
export default function Form() { const ref = useRef(null)
function handleClick() { ref.current.focus() }
return ( <form> <MyInput placeholder="Enter your name" ref={ref} /> <button type="button" onClick={handleClick}> Edit </button> </form> )}代码实例:codesandbox
总结
React 父组件想要获取子组件的实例方法,必须通过 ref 来获取。而在类组件和函数组件上有部分区别。
- 类组件可以直接通过 createRef 创建 ref 指向子组件实例,从而调用子组件内部的方法。
- 函数组件则需要使用 useImperativeHandle 暴露子组件的方法。