今天在翻看博客時,忽然發(fā)現(xiàn)有的博主在討論render props時,說到了React mixins。由于自己使用React時間不是特別長,所以對于早前的React版本的語法不是很熟悉,所以補充一下。順便做一個小的系列文章:
什么是React mixins ?
mixins(混合)是指定義一個對象,讓組件去繼承該對象的方法和狀態(tài)的過程,該對象也被稱為混入(混合)對象。若組件和被繼承的混合對象具有相同的生命鉤子函數(shù),并且在執(zhí)行該生命鉤子函數(shù)時,混合對象的函數(shù)會優(yōu)先執(zhí)行,然后再到組件內相同函數(shù)執(zhí)行,但僅限于生命鉤子函數(shù)。
另外,組件內不允許有和混合對象相同命名的方法(非生命鉤子函數(shù)),如例子中的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!"); //優(yōu)先執(zhí)行
},
handlAction:function(){
console.log("mix action!"); //該方法不允許再從組件中重構,否則會報錯
}
}
var HelloWorld = React.createClass({
mixins: [mixinCommon],
componentWillMount: function() {
console.log("HelloWorld componentWillMount!"); //仍會執(zhí)行
},
componentDidMount: function() {
this.handlAction(); //調用mixinCommon的方法
},
render: function() {
return <h1>Hello World!</h1>;
}
});
ReactDOM.render(<HelloWorld />,document.getElementById("example"));
需要注意的是:ES6 本身是不包含混入支持的。因此,如果你使用 class 關鍵字創(chuàng)建組件,那就不能使用混入功能了。我們現(xiàn)在在使用React的時候大部分都是使用class關鍵字創(chuàng)建組件,很少使用createClass來創(chuàng)建組件了。正因為如此,我們現(xiàn)在幾乎很少使用到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 做檢查,如果具有,則會發(fā)出警告,但該手段并不牢靠。
所以為了解決上述問題,在React社區(qū)有人開始大量使用高階組件HOC。參考下篇文章:React HOC(高階組件)。