React是以组合组件的形式组织的,组件因此彼此相互独立。组件中会有3种不同的可能性:父组件向子组件通信、子组件向父组件通信、没有嵌套关系的组件之间通信。
父组件向子组件通信
React数据流是单向的,父组件通过props向子组件传递需要的信息。
子组件向父组件通信
在React之前的组件开发模式时,常常需要接受组件运行时的状态,我们可以通过利用回调函数和利用自定义事件机制接受到组件的状态。
跨级组件通信
在React中子组件跨级访问时,我们可以通过层层传递的方法,但是这样代码不优雅而且当代码多的情况下有些冗余。这时我们可以通过context实现跨级父子组件间的通信。
class ListItem extends Component {
static contextType = {
color: PropTypes.string
}
render() {
const {value} = this.props
return (
<li style={{background: this.context.color}}>
</li>
)
}
}
class List extends Component {
static childContextTypes = {
color: PropTypes.string
}
getChildContext() {
return {
color: 'red'
}
}
render() {
const { list } = this.props;
return (
<div>
<ListTitle title={title} /> <ul>
{list.map((entry, index) => (
<ListItem key={`list-${index}`} value={entry.text} />
))} </ul>
</div>
)
}
}
如上,我们没有给ListItem传递props,而是在父组件中定义了ChildContext,这样从这一层开始的子组件都可以拿到定义的context。例如color
context就像一个全局变量,我们不推荐使用context,使用 context 比较的是义上的不会,如界面主题、用户信息等。
没有嵌套关系的组件通信
没有嵌套关系的组件,我们只能通过可以影响全局的一些机制去考虑,自定义事件不失为一种好的办法。
我们可以使用发布/订阅模式,可以借用Node.js Events模块浏览器版实现。
import { EventEmitter } from 'events'
export default new EventEmitter()
然后将该实例输出到各个组件中
import emmiter from './events'