日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

React Mixins入门指南

發布時間:2025/6/15 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 React Mixins入门指南 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  對于很多初級的前端工程師對mixins的概念并不是很了解,也沒有在React中嘗試使用過Mixins,這邊文章基本會按照Mixins的作用、用途、原理等多個方面介紹React中Mixins的使用。
  首先解釋一下什么是Mixins,在一些大型項目中經常會存在多個組件需要使用相同的功能的情況,如果在每個組件中都重復性的加入相同的代碼,那么代碼的維護性將會變的非常差,Mixins的出現就是為了解決這個問題。可以將通用共享的方法包裝成Mixins方法,然后注入各個組件實現,我們首先給出一個Mixins簡單的例子:

const mixin = function(obj, mixins) {const newObj = obj;newObj.prototype = Object.create(obj.prototype);for (let prop in mixins) {if (mixins.hasOwnProperty(prop)) {newObj.prototype[prop] = mixins[prop];}}return newObj; } const manMixins = {speak: function (){console.log("I'm "+this.name);} }; const Man = function() {this.name = 'wang'; }; const manCanSpeak = mixin(Man,manMixins); const man = new manCanSpeak(); man.speak(); //'I'm wang'

  上述代碼就實現了一個簡單的mixin函數,其實質就是將mixins中的方法遍歷賦值給newObj.prototype,從而實現mixin返回的函數創建的對象都有mixins中的方法。在我們大致明白了mixin作用后,讓我們來看看如何在React使用mixin。

React.createClass

  假設我們所有的React組件的props中都含有一個默認的displayName,在使用React.createClass時,我們必須給每個組件中都加入

getDefaultProps: function () {return {displayName: "component"}; }

  當然我們,我們通過實現一個mixin函數,就可以實現這個功能,并且在createClass方法使用mixin非常簡單:

var mixinDefaultProps = {getDefaultProps: function(){return {displayName: 'component'}} }var ExampleComponent = React.createClass({mixins: [mixinDefaultProps],render: function(){return <div>{this.props.displayName}</div>} });

  這樣我們就實現了一個最簡單的mixin函數,通過給每一個組件配置mixin,我們就實現了不同組件之間共享相同的方法。需要注意的是:

mixin中有相同的函數

  • 組件中含有多個mixin,不同的mixin中含有相同名字的非生命周期函數,React會拋出異常(不是后面的函數覆蓋前面的函數)。

  • 組件中含有多個mixin,不同的mixin中含有相同名字的生命周期函數,不會拋出異常,mixin中的相同的生命周期函數(除render方法)會按照createClass中傳入的mixins數組順序依次調用,全部調用結束后再調用組件內部的相同的聲明周期函數。

  • mixin中設置props或state

  • 組件中含有多個mixin,不同的mixin中的默認props或初始state中不存在相同的key值時,則默認props和初始state都會被合并。

  • 組件中含有多個mixin,不同的mixin中默認props或初始state中存在相同的key值時,React會拋出異常。

  • JSX

      目前幾乎很少有人會使用React.createClass的方式使用React,JSX + ES6成了標配,但是JavaScript在ES6之前是原生不支持的mixin的,ES7引入了decorator,首先介紹一下decorator到底是什么?

    Decorator

      ES7的Decorator語法類似于Python中的Decorator,在ES7中也僅僅只是一個語法糖,@decorator主要有兩種,一種是面向于類(class)的@decorator,另一種是面向于方法(function)的@decorator。并且@decorator實質是利用了ES5中的Object.defineProperty。

    Object.defineProperty  

      關于Object.defineProperty不是很了解的同學其實非常推薦看一下《JavaScript高級程序設計》的第六章第一節,大概總結一下:在ES5中對象的屬性其實分為兩種: 數據屬性訪問器屬性

    數據屬性

    數據屬性有四個特性:

  • configurable: 屬性是否可刪除、重新定義

  • enumerable: 屬性是否可枚舉

  • writable: 屬性值是否可修改

  • value: 屬性值

  • 訪問器屬性
  • configurable: 屬性是否可刪除、重新定義

  • enumerable: 屬性是否可枚舉

  • get: 讀取屬性調用

  • set: 設置屬性調用

  •   Object.defineProperty(obj, prop, descriptor)的三個參數是定義屬性的對象、屬性名和描述符,描述符本身也是Object,其中的屬性就是數據屬性或者訪問器屬性規定的參數,舉個栗子:

    var person = {}; Object.defineProperty(person,'name',{configurable: true,enumerable: true,writable: true,value: 'wang' }); console.log(person.name);//wang

    了解了Object.defineProperty,我們分別看下面向于類(class)的@decorator和面向于方法(function)的@decorator。

    面向方法的@decorator

      class語法其實僅僅只是ES6的一個語法糖而已,class其實質是function。并且class中的內部方法會通過Object.defineProperty定義到function.prototype,例如:

    class Person {speak () {console.log('I am Person!') } }

    會被Babel轉成:

    function Person(){}Object.defineProperty(Person.prototype,'speak',{value: function () { 'I am Person!' },enumerable: false,configurable: true,writable: true })

      Decorator函數接受的參數與Object.defineProperty類似,與對類(class)的方法使用@decorator,接受到的方法分別是類的prototype,內部方法名和描述符,@decorator會在調用Object.defineProperty前劫持,先調用Decorator函數,將返回的descriptor定義到類的prototype上。
      例如:

    function readonly(target, key, descriptor) {//可以通過修改descriptor參數實現各種功能descriptor.writable = falsereturn descriptor }class Person {@readonlyspeak () {return 'I am Person!'} }const person = new Person(); person.speak = ()=>{console.log('I am human') }

    面向類的@decorator

      當我們對一個class使用@decorator時,接受到的參數target是類本身。例如:
      

    function name (target) {target.name = 'wang' }@name class Person {}console.log(Dog.name) //'wang'

      講完了@decorator,現在讓我們回到JSX中,react-mixincore-decorators兩個庫都提供了mixin函數可用。大致讓我們看一下core-decorators庫中mixin的大致代碼:

    function handleClass(target, mixins) {if (!mixins.length) {throw new SyntaxError(`@mixin() class ${target.name} requires at least one mixin as an argument`);}for (let i = 0, l = mixins.length; i < l; i++) {const descs = getOwnPropertyDescriptors(mixins[i]);const keys = getOwnKeys(descs);for (let j = 0, k = keys.length; j < k; j++) {const key = keys[j];if (!(hasProperty(key, target.prototype))) {defineProperty(target.prototype, key, descs[key]);}}} }export default function mixin(...mixins) {if (typeof mixins[0] === 'function') {return handleClass(mixins[0], []);} else {return target => {return handleClass(target, mixins);};} }

    @mixin使用如下:

    import { mixin } from 'core-decorators';const SingerMixin = {sing(sound) {alert(sound);} };const FlyMixin = {fly() {},land() {} };@mixin(SingerMixin, FlyMixin) class Bird {singMatingCall() {this.sing('tweet tweet');} }var bird = new Bird(); bird.singMatingCall();

      我們可以看到mixin函數相當于采用Currying的方式接受mixins數組,返回

    return target => {return handleClass(target, mixins); };

    而handleClass函數的大致作用就是采用defineProperty將mixins數組中的函數定義在target.prototype上,這樣就實現了mixin的要求。

    Mixin在React中的作用

      講了這么多Mixin的東西,那么Mixin在React中有什么作用呢?Mixin的作用無非就是在多個組件中共享相同的方法,實現復用,React中的Mixin也是相同的。比如你的組件中可能有共同的工具方法,為了避免在每個組件中都有相同的定義,你就可以采用Mixin。下面依舊舉一個現實的例子。
      React的性能優化一個非常常見的方法就是減少組件不必要的render,一般我們可以在生命周期shouldComponentUpdate(nextProps, nextState)中進行判斷,通過判斷nextProps和nextState與this.pros和this.state是否完全相同(淺比較),如果相同則返回false,表示不重新渲染,如果不相同,則返回true,使得組件重新渲染(當然你也可以不使用mixin,而使用React.PureComponent也可以達到相同的效果)。并且現在有非常多的現成的庫提供如上的功能,例如react-addons-pure-render-mixin中提供了PureRenderMixin方法,首先我們可以在項目下運行:

    npm install --save react-addons-pure-render-mixin;

    然后在代碼中可以如下使用

    import PureRenderMixin from 'react-addons-pure-render-mixin'; import {decorate as mixin} from 'react-mixin' @mixin(PureRenderMixin) class FooComponent extends React.Component {constructor(props) {super(props);}render() {return <div className={this.props.className}>foo</div>;} }

    當然你也可以這樣寫:

    var PureRenderMixin = require('react-addons-pure-render-mixin'); React.createClass({mixins: [PureRenderMixin],render: function() {return <div className={this.props.className}>foo</div>;} });

    甚至這樣寫:

    import PureRenderMixin from 'react-addons-pure-render-mixin'; class FooComponent extends React.Component {constructor(props) {super(props);this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);}render() {return <div className={this.props.className}>foo</div>;} }

      因為@decorator是ES7的用法,所以必須使用Babel才能使用,所以我們需要在.babelrc文件中設置:

    {"presets": ["es2015", "stage-1"],"plugins": ["babel-plugin-transform-decorators-legacy"] }

    并安裝插件:

    npm i babel-cli babel-preset-es2015 babel-preset-stage-1 babel-plugin-transform-decorators

      之后我們就可以盡情體驗ES7的decorator了!

    總結

    以上是生活随笔為你收集整理的React Mixins入门指南的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。