组件通信
一、认识
在 React
中,数据是自顶向下单向流动的,即从父组件到子组件。这条原则让组件之间的关系变得简单且可预测。
一、Props & Callback
在构建 React
应用程序时,在多层嵌套组件来使用另一个嵌套组件提供的数据。最简单的方法是将一个 prop
从每个组件一层层的传递下去,从源组件传递到深层嵌套组件,这叫做prop drilling
。
prop drilling
的主要缺点是原本不需要数据的组件变得不必要地复杂,并且难以维护。
为了避免prop drilling
,一种常用的方法是使用React Context
。通过定义提供数据的Provider
组件,并允许嵌套的组件通过Consumer
组件或useContext Hook
使用上下文数据。
二、Ref & createRef & forwardRef & useImperativeHandle
类组件方式: 在类组件中, 可以通过 React.createRef()
将一个 ref
传给子组件,然后在父组件中调用子组件实例的方法
class Child extends React.Component {
childMethod() {
console.log('子组件的方法被调用了');
}
render() {
return <div>我是子组件</div>;
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.childRef = React.createRef();
}
handleClick = () => {
// 通过 ref 调用子组件方法
this.childRef.current.childMethod();
};
render() {
return (
<div>
<Child ref={this.childRef} />
<button onClick={this.handleClick}>调用子组件方法</button>
</div>
);
}
}
函数组件方式, 函数组件没有实例, 因此需要配合 forwardRef
和 useImperativeHandle
来暴露子组件的方法供父组件调用
import React, { useRef, forwardRef, useImperativeHandle } from 'react';
const Child = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
childMethod() {
console.log('子组件的方法被调用了');
}
}));
return <div>我是子组件</div>;
});
function Parent() {
const childRef = useRef();
const handleClick = () => {
// 调用子组件暴露的方法
childRef.current.childMethod();
};
return (
<div>
<Child ref={childRef} />
<button onClick={handleClick}>调用子组件方法</button>
</div>
);
}