minins將死,ES6的Class不對其進行支持,HOC就是解決辦法。react
那什麼是高級組件?首先你得先了解請求ES6中的class
只是語法糖
,本質仍是原型繼承
。可以更好的進行說明,咱們將不會修改組件
的代碼。而是經過提供一些可以包裹組件
的組件
, 並經過一些額外的功能來加強組件
。這樣的組件
咱們稱之爲高階組件(Higher-Order Component)。babel
ES7中的新特性decorator(裝飾器)
就是使用高階組件模式,transform-decorators-legacy
是目前babel插件轉換decorator
的,能夠研究下。下面看下如何實現React的PureRender功能(高階組件和decorator一塊兒講解)。this
PureRenderDecorator
,decorator其實就是一個高階組件。prototype
import _ from 'lodash'; function shallowEqual(objA, objB) { if (objA === objB) { return true; } if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { return false; } const keysA = Object.keys(objA); const keysB = Object.keys(objB); if (keysA.length !== keysB.length) { return false; } const bHasOwnProperty = hasOwnProperty.bind(objB); for (let i = 0; i < keysA.length; i++) { const keyA = keysA[i]; if (objA[keyA] === objB[keyA]) { continue; } // special diff with Array or Object if (_.isArray(objA[keyA])) { if (!_.isArray(objB[keyA]) || objA[keyA].length !== objB[keyA].length) { return false; } else if (!_.isEqual(objA[keyA], objB[keyA])) { return false; } } else if (_.isPlainObject(objA[keyA])) { if (!_.isPlainObject(objB[keyA]) || !_.isEqual(objA[keyA], objB[keyA])) { return false; } } else if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) { return false; } } return true; } function shallowCompare(instance, nextProps, nextState) { return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState); } function shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } /* eslint-disable no-param-reassign */ function pureRenderDecorator(component) { //覆蓋了component中的shouldComponentUpdate方法 component.prototype.shouldComponentUpdate = shouldComponentUpdate; return component;//Decorator不用返回,直接使用高階組件須要return } /***** *使用ES6 class 語法糖以下,decorator的沒試過,decorator請使用上面的,不要return *let pureRenderDecorator = component => class { * constructor(props) { * super(props); * component.prototype.shouldComponentUpdate = shouldComponentUpdate; * } * render(){ * var Component = component;//自定義組件使用時要大寫 * return ( * <Component {...this.props}/> * ) * } *} ******/ export { shallowEqual }; export default pureRenderDecorator;
如何使用?假設要使用的組件是Test插件
直接使用eslint
import React from 'react'; import { pureRenderDecorator } from "./pureRenderDecorator"; class Test extends React.Component { // component code here } export default pureRenderDecorator(Test)
經過decorator
code
import React from 'react'; import { pureRenderDecorator } from "./pureRenderDecorator"; @pureRenderDecorator export default class Test extends React.Component { // component code here }