react组件之间通讯方式其实和vue组件之间的通信类似,可以对比学习。
可以传递任意类型的数据:比如基本类型、引用类型、Map、函数、react元素(组件)等。
1、父子组件通信
- 在父组件中通过给子组件标签添加属性
- 在子组件中通过props接收数据
这里只列举了传递字符串、函数、react元素,其他类型可以自己试,方式都是一样。
// 父组件中
class Parent extends React.Component {
state = {
firstName: '百',
};
render() {
return (
<div className="bg-0069ff pa-4">
<div>父组件</div>
{/* 父组件中通过给子组件标签添加属性传值 */}
{/* 注意这里的属性名可以是任意的合法名称,在子组件中接收数据的名称保持一致 */}
<Child
firstName={this.state.firstName}
fn={() => console.log('传一个函数')}
ele={<p>传一个react元素</p>}
></Child>
</div>
);
}
}
子组件是函数组件
- 通过形参 props 接收传过来的数据,是一个对象
// 子组件是函数组件
function Child(props) { // 形参 props 接收
// 调用传过来的函数
props.fn()
return (
<div className="bg-00a364">
<div>函数子组件</div>
{/* 这里的属性名称要和父组件中传递的属性名一致 */}
<div>接收父组件传过来的值: {props.firstName}家姓</div>
{/* 将传过来的元素渲染到子组件中 */}
{props.ele}
</div>
);
}
子组件是类组件
- 直接通过 this.props.xxx 访问数据
class Child1 extends React.Component {
// 如果函数组件中有 constructor 构造函数,要将props作为参数传递给构造函数和 super ,否则在里面访问不到this.props
// 注意如果不传,并不会影响在 其他地方,比如render中通过 this.props 访问数据
// 错误
// constructor() {
// super()
// console.log(this.props) // undefined
// }
// 正确
constructor(props) {
super(props)
console.log(props)
console.log(this.props)
}
render() {
return (
<div className="bg-64B5F6">
<div>类子组件</div>
<p>接收父组件传过来的值:{this.props.firstName}家姓</p>
{this.props.ele}
</div>
);
}
}
2、子父组件通信
子组件向父组件传递数据需要用回调函数的方式,通过回调函数的参数将数据传递给父组件
- 父组件给子组件传递一个函数
- 子组件调用函数,并将要传递的数据作为回调函数的参数
class Parent extends React.Component {
state = {
childData: ''
}
getChildData = (data) => {
console.log('接收子组件传过来的数据', data)
this.setState({
childData: data
})
}
render() {
return (
<div className="bg-0069ff pa-4">
<div>父组件</div>
<div>接收到了子组件传递的数据: {this.state.childData}</div>
<Child fn={this.getChildData}></Child>
</div>
);
}
}
function Child (props) {
function handleClick () {
// 调用父组件传过来的函数,并传递参数
props.fn('这是给父组件的一些data')
}
return (
<div className="bg-00a364">
<div>子组件</div>
<button onClick={handleClick}>点我, 发送数据给父组件</button>
</div>
);
}
3、兄弟组件通信
这里主要说的是两个组件在同一个父组件中,两个子组件处于平级的情况,其他情形如果使用状态提示比较繁琐时,建议通过 context 或者 事件对象(events)的方式。
兄弟组件通信是使用 状态提升 的方法,将要传递的数据提升到最近的共同的父组件中,然后进行传递和修改操作。
// 共同的父组件
class Counter extends React.Component {
state = {
count: 1,
};
addNum = () => {
this.setState({
count: this.state.count + 1,
});
};
render() {
return (
<div>
<div>计数器</div>
<Child1 count={this.state.count}></Child1>
<Child2 fn={this.addNum}></Child2>
</div>
);
}
}
// 兄弟组件1
function Child1(props) {
return <div>当前值是: {props.count}</div>;
}
// 兄弟组件2 中的按钮被点击之后,需要更新组件1中的当前值
function Child2(props) {
return <button onClick={() => props.fn()}>+1</button>;
}
完