组件间通信大致有以下三种情况:
- 父组件向子组件通信
- 子组件向父组件通信
- 跨级组件通信
父组件向子组件通信
这是最常见的一种通信方式,即父组件通过props
向子组件传递需要的信息。
子组件向父组件通信
利用回调函数可以实现通信,即父组件将一个函数作为 props
传递给子组件,子组件调用该回调函数,便可以向父组件通信。
跨级组件通信
所谓跨级组件通信,就是父组件向子组件的子组件通信,向更深层的子组件通信。
我们完全可以通过props
层层传递,但是代码将显得冗余。
此时,context完全可以更优雅的实现跨级组件通信。context就像一个全局变量。
父组件需要定义
childContextTypes
作为context
的声明和验证,通过getChildContext
方法返回一个对象。
如果一个组件设置了
context
,那么它的子组件都可以直接访问到里面的内容,它就像这个组件为根的子树的全局变量。任意深度的子组件都可以通过contextTypes
来声明你想要的context
里面的哪些状态,然后可以通过this.context
访问到那些状态。
代码:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
class Home2 extends Component {
static contextTypes = {
color: PropTypes.string
}
render() {
console.log(this.context)
return (
<div>
<div>Home2的颜色: {this.context.color}</div>
</div>
)
}
}
class Home1 extends Component {
static contextTypes = {
color: PropTypes.string
}
render() {
console.log(this.context)
return (
<div>
<div>Home1的颜色: {this.context.color}</div>
<Home2/>
</div>
)
}
}
class Home extends Component {
static childContextTypes = {
color: PropTypes.string
}
getChildContext() {
return {
color: 'red'
}
}
render() {
return (
<div>
<h1>验证Context</h1>
<Home1 />
</div>
)
}
}
export default Home
运行结果:
context 打破了组件和组件之间通过 props 传递数据的规范,极大地增强了组件之间的耦合性。而且,就如全局变量一样,context 里面的数据能被随意接触就能被随意修改,每个组件都能够改 context 里面的内容会导致程序的运行不可预料。
但是这种机制对于前端应用状态管理来说是很有帮助的,因为毕竟很多状态都会在组件之间进行共享,context 会给我们带来很大的方便。一些第三方的前端应用状态管理的库(例如 Redux)就是充分地利用了这种机制给我们提供便利的状态管理服务。但我们一般不需要手动写 context,也不要用它,只需要用好这些第三方的应用状态管理库就行了。