今天在翻看博客时,忽然发现有的博主在讨论render props时,说到了React mixins。由于自己使用React时间不是特别长,所以对于早前的React版本的语法不是很熟悉,所以补充一下。顺便做一个小的系列文章:
什么是React mixins ?
mixins(混合)是指定义一个对象,让组件去继承该对象的方法和状态的过程,该对象也被称为混入(混合)对象。若组件和被继承的混合对象具有相同的生命钩子函数,并且在执行该生命钩子函数时,混合对象的函数会优先执行,然后再到组件内相同函数执行,但仅限于生命钩子函数。
另外,组件内不允许有和混合对象相同命名的方法(非生命钩子函数),如例子中的handlAction,否则会报错:
ReactClassInterface: You are attempting to define `handlAction` on your component more than once. This conflict may be due to a mixin.
// 混合
const mixinCommon = {
componentWillMount: function() {
console.log("mix componentWillMount!"); //优先执行
},
handlAction:function(){
console.log("mix action!"); //该方法不允许再从组件中重构,否则会报错
}
}
var HelloWorld = React.createClass({
mixins: [mixinCommon],
componentWillMount: function() {
console.log("HelloWorld componentWillMount!"); //仍会执行
},
componentDidMount: function() {
this.handlAction(); //调用mixinCommon的方法
},
render: function() {
return <h1>Hello World!</h1>;
}
});
ReactDOM.render(<HelloWorld />,document.getElementById("example"));
需要注意的是:ES6 本身是不包含混入支持的。因此,如果你使用 class 关键字创建组件,那就不能使用混入功能了。我们现在在使用React的时候大部分都是使用class关键字创建组件,很少使用createClass来创建组件了。正因为如此,我们现在几乎很少使用到mixins了。
React mixins在解决什么问题,本身存在什么问题 ?
回答上述问题之前,我们再来看一个mixins的典型🌰:
import React from 'react'
import ReactDOM from 'react-dom'
// mixin 中含有了你需要在任何应用中追踪鼠标位置的样板代码。
// 我们可以将样板代码放入到一个 mixin 中,这样其他组件就能共享这些代码
const MouseMixin = {
getInitialState() {
return { x: 0, y: 0 }
},
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
})
}
}
const App = React.createClass({
mixins: [ MouseMixin ],
render() {
const { x, y } = this.state
return (
<div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
<h1>The mouse position is ({x}, {y})</h1>
</div>
)
}
})
ReactDOM.render(<App/>, document.getElementById('app'));
很简单,如果有好几处地方需要使用鼠标的X和Y坐标,只需要轻松的将 MouseMixin 混入他们的组件中,并通过 this.state 属性获得鼠标的 x 和 y 坐标。所以mixin很显然是为了解决代码复用的问题。
但是这种解决方式并不是非常完美无瑕,具体原因总结如下:
- ES6 class不支持 mixins。
- 不够直接。minxins 改变了 state,因此也就很难知道一些 state 是从哪里来的,尤其是当不止存在一个 mixins 时。
- 名字冲突。两个要更新同一段 state 的 mixins 可能会相互覆盖。createClass API 会对两个 mixins 的 getInitialState 是否具有相同的 key 做检查,如果具有,则会发出警告,但该手段并不牢靠。
所以为了解决上述问题,在React社区有人开始大量使用高阶组件HOC。参考下篇文章:React HOC(高阶组件)。
网友评论