React 父组件调用子组件的方法
2023 react在 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 暴露子组件的方法。