在React中使用mixin

mixin到底为何方神圣?

mixin被理解为‘混入’的意思,
我们知道,如果你经常使用某一段相同的代码的时候,你会把它进行抽象,封装成类或者function,
‘混入’也一样,它可以解决代码段重复的问题。

jade中的Mixins

jade(pug)是一个高性能的模版引擎,它使用javascript实现,并提供给Node使用.
我在使用Jade模版引擎接触到了Mixin, 下面给出一个例子理解下

1
2
3
4
5
6
7
8
9
10
mixin box(styles)
.conponent
-each style in styles
.squire
-var x = styles.indexOf(style) + 1;
a(href='/users/' + x + '/list') #{style}
.container
mixin(['lin', 'limoer'])
.links
mixin(['parents', 'classmates', 'others'])

你可以无视jade的语法,如果你想学习jade,点这里

首先我使用mixin 关键字申明了一个带参数mixin结构,然后依据传入的参数生成了很多url
这个mixin 结构可以在这个模版文件中使用,通过不同的参数来生成url
从上面可以看出,mixin的确可以解决代码重复的问题

React中的Mixin

首先来写一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var TimerComp = React.createClass({
getInitialState: function() {
return {secondsElapsed: 0}
},
tick: function() {
this.stateState({secondsElapsed: this.state.secondsElapsed + 1})
},
componentDidMount: function() {
this.interval = setInterval(this.tick, 1000)
},
componentWillUnmount: function() {
clearInterval(this.interval)
},
render: function(){
return (
<div>
<p>Seconds Elapse {this.state.secondsElapsed}</p>
</div>
)
}
});

简单的说一下,这里定义了一个定时器组件,会随着时间的增加来自动计时
但是一个应用需要多个计时器呢?我们第一时间想到了组件的嵌套,但是组件的嵌套不但会增加组件的复杂程度
而且,想要修改计时器也是比较困难的
好了,解决代码复用的问题,我们可以使用Mixin, 让其混入进其他组件就好了

码起,还是计时器的例子!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var MixinTimerComp = React.createClass({
mixins: [MixinInterval(1000)],
getInitialState: function() {
return {secondsElapsed: 0}
},
onTick: function(){
this.setState({secondsElapsed: this.state.secondsElapsed + 1})
},
render: function(){
return (
<div>
<p>Seconds Elapse {this.state.secondsElapsed}</p>
</div>
)
}
});

这里我们使用了mixins属性,把自定义的MixinInterval对象混入了Timer组件

来看看MixinInterval的实现:

1
2
3
4
5
6
7
8
9
10
var MixinInterval: function(interval) {
return {
componentDidMount() {
this.__interval = setInterval(this.onTick, interval)
},
componentWillUnmount() {
clearInterval(this.__interval)
}
}
};

就这样实现了一个最简单的问题,和最前面的例子做对比,我们发现,只是把组件中一些代码独立出来成为一个mixin对象
但这样做无疑是解决了代码重用的问题,当我们想定义另一个计时器时候,我们只需混入这个mixin代码
而不必关心混入的计时处理对象是怎么实现的

mixin 实现起来非常简单,React也支持多个mixin的混入(在mixins赋值为一个mixin对象数组)
但有一个问题需要注意,在mixin中尝试覆盖state中定义的键的话,React会抛出错误

1
2
3
4
5
6
7
8
9
10
11
React.createClass({
mixins: [{
getInitialState(){
return {cover: 1}
}
}],
getInitialState(){
return {cover: 2}
}
})
// 错误,尝试覆盖cover属性
分享到 评论