在项目开发的过程当中,随着应用功能复杂度的增长和组件层次划分的需求,组件之间的通讯愈来愈多,
我大体认为组件之间的通讯分为3种:父-子组件通讯、子-父组件通讯和同级组件之间的通讯。app
1.父-子组件通讯函数
2.子-父组件通讯this
3.同级组件之间的通讯spa
这是最多见的通讯方式,父组件只须要将子组件须要的props传给子组件,子组件直接经过this.props来使用。设计
更多要提的是如何合理的设置子组件的props,要想将子组件设计成一个复用性强的通用组件,须要将可以复用的部分抽象出来,
抽象出来的props有两种造成,一种是简单的变量,另外一种是抽象出来处理某种逻辑的函数。code
以Header 组件为例orm
抽象出来三个props,分别是中间的title,渲染组件左边的renderLeftComponent,渲染组件右边的renderRightComponent
Header的 部分实现事件
renderLeftComponent () { let leftDOM = {}; if(this.props.renderLeftComponent) { return this.props.renderLeftComponent(); } if (this.props.showBack) { let backFunc = this.props.onBack || this.goBack; leftDOM = (<a onClick={backFunc.bind(this)}><i className="icon left-icon icon-left-arrow"></i></a>); } return leftDOM; } renderRightComponent () { if(this.props.renderRightComponent) { return this.props.renderRightComponent(); } } render () { return ( <header className="header-wrapper"> <div className="header header-normal"> {this.renderLeftComponent()} <span>{this.props.title || '维C果蔬'}</span> {this.renderRightComponent()} </div> </header> ); }
1.1中Header组件 props的通讯动机 是子组件须要这样的属性来完成本身的展现。还有一种动机能够统称向子组件传递监听事件,
前一种是子组件的需求,后一种更多的是父组件的需求,例如Listview的onEndReached这种属性,触发源是在子组件中,当子组件
的事件被触发或者达到某种状态的时候,调用父组件从属性中传过来的方法。ip
父-子组件通讯的手段是经过子组件的props是子组件用父组件的东西,子-父组件通讯,是父组件用子组件的东西,应该将传递的内容直接写在子组件上,而后给子组件设置ref,父组件直接经过ref操做子组件的属性。开发
子组件的属性
父组件想要调用子组件的属性
同级组件之间的通讯,是构建复杂界面的粘合剂,哎呦喂,我好会比喻啊
以维C果蔬的首页为例:
通讯1: Listview须要offsetHeight属性,Listview
Height的计算公式:window.innerHeight-Banner的Height-Menu的Height,
而Banner和Menu的Height都是须要在其Mount的时候才能计算。
通讯2: ListView须要Menu的MenuId,才可以根据MenuId获取sku数据。
同级组件之间的通讯仍是须要经过父组件做为中介,利用屡次父-子组件通讯,项目中将须要传递的数据放在了父组件的state中,变更时能够自动的同步传递。
将 bannerHeight,menuHeight,MenuId放在state中。
父组件代码示意:
this.state { bannerHeight: 0, menuHeight: 0, MenuId: 0 } setBannerHeight(height) { this.setState({bannerHeight:height}); } setMenuHeight(height) { this.setState({menuHeight:height}); } onMenuClick(menuId) { this.setState({menuId:menuId}); } <Banner setBannerHeight={this.setBannerHeight.bind(this)} /> <Menu setMenuHeight={the.setMenuHeight.bind(this)} onMenuClick={this.onMenuClick.bind(this)} /> <SkuList offsetHeight={this.state.bannerHeight + this.state.menuHeight} menuId={this.state.menuId} />
当组件须要的props,不能直接从父组件中获取时,须要父组件做为中介,再与其余的组件进行通讯获取。