《React+Redux前端开发实战》—2.3.3 跨级组件通信
2.3.3 跨级组件通信
当组件层层嵌套时,要实现跨组件通信,首先会想到利用props一层层去传递信息。虽然可以实现信息传递,但这种写法会显得有点“啰嗦”,也不优雅。这种场景在React中,一般使用context来实现跨级父子组件通信。
context的设计目的就是为了共享对于一个组件树而言是“全局性”的数据,可以尽量减少逐层传递,但并不建议使用context。因为当结构复杂的时候,这种全局变量不易追溯到源头,不知道它是从哪里传递过来的,会导致应用变得混乱,不易维护。
context适用的场景最好是全局性的信息,且不可变的,比如用户信息、界面颜色和主题制定等。
context实现的跨级组件通信示例(React 16.2.0):
(源码地址为https://jsfiddle.net/allan91/Lbecjy18/2/)
// 子(孙)组件
class Button extends React.Component {
render() {
return (
<button style={{background: this.context.color}}>
{this.props.children}
</button>
);
}
}
// 声明contextTypes用于访问MessageList中定义的context数据
Button.contextTypes = {
color: PropTypes.string
};
// 中间组件
class Message extends React.Component {
render() {
return (
<div>
<Button>Delete</Button>
</div>
);
}
}
// 父组件
class MessageList extends React.Component {
// 定义context需要实现的方法
getChildContext() {
return {
color: "orange"
};
}
render() {
return <Message />;
}
}
// 声明context类型
MessageList.childContextTypes = {
color: PropTypes.string
};
ReactDOM.render(
<MessageList />,
document.getElementById('container')
);
上述代码中,MessageList为context的提供者,通过在MessageList中添加childContextTypes和getChildContext()和MessageList。React会向下自动传递参数,任何组织只要在它的子组件中(这个例子中是Button),就能通过定义contextTypes来获取参数。如果contextTypes没有定义,那么context将会是个空对象。
context中有两个需要理解的概念:一个是context的生产者(provider);另一个是context的消费者(consumer),通常消费者是一个或多个子节点。所以context的设计模式是属于生产-消费者模式。在上述示例代码中,生产者是父组件MessageList,消费者是孙组件Button。
在React中,context被归为高级部分(Advanced),属于React的高级API,因此官方不推荐在不稳定的版本中使用。值得注意的是,很多优秀的React第三方库都是基于context来完成它们的功能的,比如路由组件react-route通过context来管理路由,react-redux的<Provider/>通过context提供全局Store,拖曳组件react-dnd通过context分发DOM的Drag和Drop事件等。
注意:不要仅仅为了避免在几个层级下的组件传递props而使用context,context可用于多个层级的多个组件需要访问相同数据的情景中。
- 点赞
- 收藏
- 关注作者
评论(0)