React中父组件与子组件之间的数据传递的的实现你们均可以轻易作到,但对比不少人的实现方法,老是会有或多或少的差别。在一个团队中,这种实现的差别体现了每一个人各自的理解的不一样,可是反过来思考,一个团队用了一样的UI,一样的框架,实现方式确实有差别,这其实就是工程化的问题。前端
回到React中父组件与子组件之间的数据传递的问题上来。编程
父组件与子组件之间的数据传递的实现方式大体能够分为2种状况:架构
一、子组件用本身的flux环传递数据,最后调用父组件的onChange事件将数据传给父组件。框架
二、子组件调用父组件的onChange事件,在父组件中的onChange事件中调用flux环传递数据到付组件的View层工具
这2种方式各有优势,对比这两种方式,在实时性上,第二种方式是经过调用父组件的onChange事件,数据改变是经过父组件的flux环发生改变的,因此是实时的,而第一种方式的数据是经过子组件本身的flux环改变的,最终传给父组件,因此非实时;而在粒度上,这2种方式是相同的,都是维护了一个局部逻辑。咱们通常用子组件来实现一些页面局部的复杂逻辑,若是这个逻辑内部的数据处理也很复杂(要根据各类状况做出不一样的断定、改变),那么第一种无疑更为合适,而更为现实的状况是,每每局部的复杂逻辑的实如今子组件内部还有子组件的子组件,这种状况下,优先选择第一种方式;那么相对的若是这个数据处理比较简单,咱们彻底能够将整个子组件看作页面上的一个输入框(也能够是其余实现某个功能的对话框),那么父组件中的一个输入框调用父付组件的onChange事件来改变数据流,毫无疑问,第二种方式更为合理些。ui
按照第二种方式,咱们常常能够在父组件中看到以下的局部代码:this
onChange: function(property, value) { Action.changePromotionDetail(property, value); }, render: function() { return ( <div className="xui-promotion-flashSalePage"> <ProductInfo onChange={this.onChange} /> <PromotionInfo onSubmit={this.onSubmit} onChange={this.onChange} promotionName={this.state.promotionName} advert={this.state.advert} promotionRangeDate={this.state.promotionRangeDate} memberGrades={this.state.memberGrades} memberGrade={this.state.memberGrade} promotionPrice={this.state.promotionPrice} numPerPurchase={this.state.numPerPurchase} period={this.state.period} numPerPeriod={this.state.numPerPeriod} /> </div> ) }
若是传入子组件的属性和方法越多,那么代码的可读性其实越差,维护起来也更不方便,甚至在父组件的Store中还须要对数据流作许多处理,相似:spa
changePromotionDetail: function(action) {
if (...) {
this.data[action.data.property] = ...;
} else {
this.data[action.data.property] = action.data.value;
}
this.__emitChange();
}
那么咱们又须要思考,若是咱们像上面所说的将子组件看作一个输入框,一个输入框应该只须要输入一个值,父组件不该该接受那么多的不一样属性的数据,同时父组件须要作的只是将接受到的一个数据经过flux环传递给父组件的View层。那么咱们能够采用的一种方法是子组件的数据变动先调用子组件的onChange事件,并在其中作好必要的数据处理,而后将数据添加到一个对象中,以一个数据处理完毕的对象的形式调用父组件的onChange事件:code
onChange: function(property, value) {
if (property == '...') {
// do someting here...
} else {
// do someting here...
}
var obj = {
// some key/value here
};
this.props.onChange(obj);
}
这样父组件中的代码就能够简化为以下:对象
onChange: function(obj) { Action.changePromotionDetail(obj); }, render: function() { return ( <div className="xui-promotion-flashSalePage"> <ProductInfo onChange={this.onChange} /> <PromotionInfo onSubmit={this.onSubmit} onChange={this.onChange} infoObj={this.state.infoObj} /> </div> ) }
再回到标准化的思考上,以React为例,React自己只是一个UI,facebook推荐了flux的架构,这就是一种实现方式,那么一个团队在大方向上采用的技术和实现方式其实就肯定了下来。若是咱们进一步的细分,对诸如父组件和子组件之间的数据传递的方式,数据传递的格式等等做出限制,看上去好像限制了研发编程的自由,同时将研发的工做变成了机械的重复,可是换个角度,这样的限制必然提升了研发效率,每一个人碰到不一样的场景都有了统一的应对策略;这样的限制也必然下降维护的成本,每一个人都能理解他人的编程思路。这就是工程化的一部分。
编程就是为了解决问题,要想解决问题又须要考虑2个问题:
一、工具。
二、方式。
工具是学不完的,尤为如今前端的工具井喷式的发展(虽然侧面说明了前端工具的匮乏~),到这个公司用React,之后跳槽去了另外一家又用Angular,后来换了部门,这个部门又用Vue。
那么,做为研发,或许能够思考第二个问题,标准化的方式。每一个公司每一个部门都会有一套标准,你须要作的是先学会这套标准,同时去思考能够完善的地方,譬如这种场景没有标准化的解决方案,你能够提出一个方案,若是被你们接受了,你的方案就成为了标准的一部分。
这或许也是一条前端之路,一条提升编程效率与维护性的路,一条解决工程化部分问题的路。