组件的协同本质上是对组件的组织和管理方式
目的:
- 逻辑清晰 组件之间
- 代码模块化 便于管理模块
- 封装细节
- 代码可复用
- 组件嵌套 封装
- Mixin 复用
本质是父子关系
父组件跟子组件通信:通过传递属性实现
子组件跟父组件通信:委托,父组件可以编写事件处理函数,父组件为子组件添加相应的事件处理,然后子组件触发该事件,实现子组件到父组件的通信
优点:
- 逻辑清晰:父子关系和人类社会的父子关系对应,易于理解
- 代码模块化:每个模块对应一个功能,不同模块可以同步开发
- 封装细节:开发者只需要关注组件的功能,不用关心组件的实现细节
缺点:
- 编写难度高:父子关系的具体实现需要经过深思熟虑,贸然编写将导致关系混乱,代码难以维护
- 无法掌握所有细节:开发者只知道组件的用法,不知道组件的细节,难以维护
<span style="font-size:18px;">$(function(){
var GenderSelect=React.createClass({
render:function(){
return(
<select onChange={this.props.handleSelect}>
<option value="0">男</option>
<option value="1">女</option>
</select>);
}
});
var SignupForm=React.createClass({
getInitialState:function(){
return{
name:"",
password:"",
gender:""
}
},
handleChange:function(name,event){
var newState={};
newState[name]=event.target.value;
this.setState(newState,null);
},
/**
* 委托:父组件给子组件绑定一个事件处理函数,通过子组件的触发事件来与父组件进行通信
*/
handleSelect:function(event){
this.setState({gender:event.target.value},null);
},
render:function(){
console.log(this.state);
return <form>
<input type="text" placeholder="please input username"
onChange={this.handleChange.bind(this,"name")}/>
<input type="password" placeholder="please input password"
onChange={this.handleChange.bind(this,"password")} />
<GenderSelect handleSelect={this.handleSelect}/>
</form>
}
});
ReactDOM.render(<SignupForm/>,document.getElementById("app"));
});</span>
Mixin:
Mixin 一组方法
目的:横向抽离出组件的相似代码
相似概念:面向切面编程,插件
Mixin 一组方法
目的:横向抽离出组件的相似代码
相似概念:面向切面编程,插件
优点:
- 代码复用:抽离出通用代码,减少开发成本,提高开发效率
- 即插即用:可以直接使用许多现有的Mixin来编写自己的组件
- 适应性强:改动一次代码,影响多个组件
缺点:
- 编写难度高:Mixin可能被用在各种环境中,兼容多种环境就需要更多的逻辑和代码,通用的代码提供了复杂度
- 降低代码可读性:组件的优势在于将逻辑和界面直接结合在一起Mixin本质上会分散逻辑,理解起来难度更大
<span style="font-size:18px;">var SetIntervalMixin={
componentWillMount:function(){
this.intervals=[];
},
setInterval:function(){
this.intervals.push(setInterval.apply(null,arguments));
},
componentWillUnmount:function(){
this.intervals.map(clearInterval);
}
};
var TickTock=React.createClass({
minxins:[SetIntervalMixin],
getInitialState:function(){
return{
second:0
}
}
})</span>
<span style="font-size:18px;"> var ChangeMixin={
handleChange:function(key){
var that=this;
return function(event){
var newState={};
newState[key]=event.target.value;
that.setState(newState,null);
}
}
}
var HelloWorld=React.createClass({
mixins:[ChangeMixin],
getInitialState:function(){
return {
text:"",
comment:""
}
},
render:function(){
return <div>
<input type="text" placeholder="text" onChange={this.handleChange("text")}/>
<textarea cols="30" rows="10" onChange={this.handleChange("comment")}></textarea>
<p>{this.state.text}</p>
<p>{this.state.comment}</p>
</div>;
}
});
ReactDOM.render(<HelloWorld/>,document.getElementById("app"));</span>