React 组件通信02

React 组件通信 02

跨级组件通信

跨级组件通信就是父组件与子组件的子组件或者更深层次的通信。我们可以让父组件传给子组件,再让子组件传递给他的子组件,一次逐级传递。但是这种传递方式当层级关系超过两层的时候会过于臃肿,不好维护。Contex 通过组件树提供了一个传递数据的方法,从而避免在每个层级之间手动传递 props 属性。

祖先代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from "react";
import PropTypes from "prop-types"; // 用于属性校验,想了解更多见文末的扩展阅读。
import Sub from "./Sub.js"; // 中间组件
export default class App extends React.Component {
// 在父组件定义上下文(Context)
static childContextTypes = {
// 声明静态属性 必须要写
color: PropTypes.string, // PropTypes 用于校验属性类型
callback: PropTypes.func, // 回调函数
};
getChildContext() {
// 用于返回上下文(Context)的值便于后代获取
return {
color: "pink",
callback: this.callback.bind(this), // 需要绑定this
};
}
callback(msg) {
alert(msg);
}
render() {
return <Sub />;
}
}

中间组件代码示例:

1
2
3
4
5
import React from "react";
import SubSub from "./SubSub.js"; // 后代组件
export default function Sub(props) {
return <SubSub />;
}

后代组件代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from "react";
import PropTypes from "prop-types"; // 用于属性校验,想了解更多见文末的扩展阅读。
export default class SubSub extends React.Component {
static contextTypes = {
// 后代组件必须校验属性类型
color: PropTypes.string,
callback: PropTypes.func,
};
render() {
const style = { color: this.context.color }; // 通过 this.context 获取上下文的值
const cb = (msg) => {
return () => {
this.context.callback(msg);
};
};
return (
<div style={style}>
<h1>In SubSub.js</h1> // 粉色字体展示 In SubSub.js
<button onClick={cb("this is SubSub.js")}>click me</button> // 点击按钮,弹出
this is SubSub.js 字样
</div>
);
}
}

以上可以看出,祖先组件声明了 context 上下文,后代组件通过 this.context 获取祖先组件传递下来的内容

注意:如果后代组件使用构造函数 Constructor,那么 context 需要作为构造函数的第二个参数传入,否则无法使用

1
2
3
4
constructor (props, context) {
super(props)
...
}