Mixin的作用
当我们在不同的组件中使用很多的相同的功能的时候,这个时候就会出现大量的相似的代码,累赘的厉害。而Mixin就是解决这个问题。
一个简单的Mixin的小案例
<script type="text/babel">
var DefaultNameMixin={
getDefaultProps:function(){
return {name:'Picky'};
}
}
var ComponentOne=React.createClass({
mixins:[DefaultNameMixin],
render:function(){
return (
<h2>{this.props.name}</h2>
)
}
});
ReactDOM.render(<ComponentOne></ComponentOne>,document.body);
</script>
假设我们现在要在好几个组件中设置默认的name属性,以前的处理方法是在每一个组件中都写一个相同的getDefaultProps的方法。现在,我们可以使用mixin,像上面所示,定义一个mixin,创建一个简单的对象:DefaultNameMixin。
使用mixin:我们只需要在组件中加入mixin属性,然后,把我们刚才写的mixin包裹成一个数组,将它作为该属性的值就可以啦。
重复使用Mixin
我们可以在多个组件中重复的使用同一个Mixin
<script type="text/babel">
var DefaultNameMixin={
getDefaultProps:function(){
return {name:"picky"};
}
};
var ComponentOne=React.createClass({
mixins:[DefaultNameMixin],
render:function(){
return (
<h2>{this.props.name}</h2>
)
}
});
var ComponentTwo=React.createClass({
mixins:[DefaultNameMixin],
render:function(){
return (
<div>
<h4>{this.props.name}</h4>
<p>food:{this.props.food}</p>
</div>
);
}
});
var OuterComponent=React.createClass({
render:function(){
return (
<div>
<ComponentOne></ComponentOne>
<ComponentTwo food="apple"></ComponentTwo>
</div>
)
}
});
ReactDOM.render(<OuterComponent></OuterComponent>,document.body);
</script>
生命周期的方法会被重复调用
<script type="text/babel">
var DefaultName={
getDefaultProps:function(){
return {name:"Dog"};
}
};
var ComponentOne=React.createClass({
mixins:[DefaultName],
render:function(){
return (
<h2>{this.props.name}</h2>
);
}
});
var ComponentTwo=React.createClass({
mixins:[DefaultName],
getDefaultProps:function(){
return {
food:"apple"
};
},
render:function(){
return (
<div>
<h4>{this.props.name}</h4>
<p>food:{this.props.food}</p>
</div>
);
}
});
var OuterComponent=React.createClass({
render:function(){
return (
<div>
<ComponentOne></ComponentOne>
<ComponentTwo></ComponentTwo>
</div>
);
}
});
ReactDOM.render(<OuterComponent></OuterComponent>,document.body);
</script>
两个getDefaultProps的方法都会被调用,我们会得到两个默认的name属性和food属性的值,任何生命周期的方法和属性都会被重复的调用,下面的情况除外:
- render:包含多个render的方法是不行的,react会报错。
- displayName:你多次的对它进行设置是没有问题的,但是,最终的结果只以最后一次设置为准。
需要指出的是,mixin是可以包含在其他的mixin中的:
<script type="text/babel">
var UselessMixin={
componentDidMount:function(){
console.log('great!');
}
};
var LolMixin={
mixins:[UselessMixin]
};
var Component=React.createClass({
mixins:[LolMixin],
render:function(){
return <p>I do!</p>
}
});
ReactDOM.render(<Component></Component>,document.body);
</script>
会打印出:great!
多个生命周期方法的调用顺序
如果我们的组件和mixin中都包含了相同的生命周期的方法,那么,我们的mixin方法首先会被调用,然后是我们组件中的方法调用。
当我们的组件中有多个mixn,而mixin中又包含相同的生命周期的方法,那么,它会根据mixin中的顺序从左到右进行调用。
<script type="text/babel">
var LogOnMountMixin={
componentDidMount:function(){
console.log("a");
}
};
var MoreLogOnMountMixin={
componentDidMount:function(){
console.log("b");
}
};
var ComponentOne=React.createClass({
mixins:[LogOnMountMixin,MoreLogOnMountMixin],
componentDidMount:function(){
console.log("c");
},
render:function(){
return <p>1</p>;
}
});
var ComponentTwo=React.createClass({
mixins:[MoreLogOnMountMixin,LogOnMountMixin],
componentDidMount:function(){
console.log("d");
},
render:function(){
return <p>2</p>;
}
});
ReactDOM.render(
<div>
<ComponentOne></ComponentOne>
<ComponentTwo></ComponentTwo>
</div>,document.body);
</script>
会打印出:
a b c
a b d
注意事项
- 我们的mixins要包裹在数组中,这就说明,一个组件可以包含多个mixin
- 设置相同的prop和state会报错也就是说,在不同的地方定义相同的属性会报错
- 在不同的mixin中定义相同的方法,或者是mixin和组件中都包含了相同的方法的时候,出现异常