一.组件通讯介绍
组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据。在组件化过程中,我们将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能。而在这个过程中,多个组件之间不可避免的要共享某些数据。为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通。这个过程就是组件通讯。
二.组件的 props
- 组件是封闭的,要接收外部数据应该通过 props 来实现
- props 的作用:接收传递组件的数据
- 传递数据:给组件标签添加属性
- 接收数据:函数组件通过参数 props 接收数据,类组件通过 this.props 接收数据
<Hello name="Jack" age={19} />
function Hello(props){
console.log(props);
return (
<div>接收到数据:{props.name}</div>
);
}
class Hello extends React.Component{
render(){
return (
<div>接收到的数据:{this.props.age}</div>
);
}
}
1.特点
- 可以给组件传递任意类型的数据
- props 是只读的对象,只能读取属性的值,无法修改对象
- 注意:使用类组件时,如果写了构造函数,应该将 props 传递给 super(),否则,无法在构造函数中获取到 props!
class Hello extends React.Component{
constructor(props){
//推荐将 props 传递给父类构造函数
super(props);
}
render(){
return <div>接收到的数据:{this.props.age}</div>;
}
}
三.组件通讯的三种方式
1. 父组件传递数据给子组件
- 父组件提供要传递的 state 数据
- 给子组件标签添加属性,值为 state 中的数据
- 子组件中通过 props 接收父组件中传递的数据
import React from 'react';
function Child(props) {
return <div>子组件接收到数据:{props.name}</div>
}
class Hello extends React.Component{
state = {lastName: '许'}
render(){
return <div>
传递数据给子组件:<Child name={this.state.lastName} />
</div>;
}
}
export default Hello;
2. 子组件传递数据给父组件
思路:利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数。
- 父组件提供一个回调函数(用于接收数据)
- 将该函数作为属性的值,传递给子组件
- 子组件通过 props 调用回调函数
- 将子组件的数据作为参数传递给回调函数
import React from 'react';
export default class Parent extends React.Component {
getChildMsg = (msg) => {
alert('接收到子组件消息', msg)
}
render() {
return <div>
子组件:<Child getMessage={this.getChildMsg} />
</div>
}
}
class Child extends React.Component {
state = {childMsg: 'React'};
handleClick = () => {
this.props.getMessage(this.state.childMsg);
}
render(){
return (
<button onClick={this.handleClick}>点我,给父组件传递数据</button>
);
}
}
注意:回调函数中 this 指向问题!
3.兄弟组件
- 将共享状态提升到最近的公共组件中,由公共父组件管理这个状态
- 思想:状态提升
- 公共父组件职责:1.提供共享状态 2.提供操作共享状态的方法
- 要通讯的子组件只需通过 props 接收状态或操作状态的方式
四.Context
思考:App 组件要传递数据给 Child 组件,该如何处理?如果使用 props 一层层组件往下传递就会很繁琐:
而更好的方法就是使用 Context 来进行跨组件传递数据(比如:主题、语言等):
1.使用步骤:
- 调用 React.createContext() 创建 Provider(提供数据)和