iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
0
自我挑戰組

React 30 天學習歷程系列 第 4

【Day 4】React 中常用的一些 ES6 語法 (二)

  • 分享至 

  • xImage
  •  

ES6 箭頭函式的一些運用

函式返回值為物件時的寫法

const userData = user => ({ name: user.name, age: user.age });

使用解構賦值時

參數為物件

//原本寫法
const userData = user => ({ name: user.name, age: user.age });

//解構賦值,先將 name, age 解構取出,就可以賦值使用
const userData = ({name, age}) => ({name, age});

參數為陣列

const test = ([x, y]) => x + y; 

箭頭函式嵌套

JS 函式是先定義後調用,如下

function test(x, y) {
    return x + y;
};

test(1, 2);//3

也允許在函式中嵌入函數做使用

function test1(x, y) {
    function test2(x, y) {
        return x + y;
    };
    return test2(3, 3) + test2(x, y);  
};

test1(4, 4);//14

在箭頭函式中,嵌套如下

const test1 = x => y => x + y;

//等於下面這種

function test1(x) {
    return function test2(y) {
        return x + y;
    };    
};

class 類

ES6 新增了 class 作為 ES5 中原型寫法的一個語法糖,相較原型鍊的寫法,class 能夠更簡潔易懂的達到繼承的目的。

基本使用

首先要定義一個 class,並定義構造函數。如果 class 內沒有定義構造函數,則默認 class 的構造函數 counstuctor 為空函數,即使沒寫也會存在,只是不會顯示。

class Count {}

// counstuctor 即使沒寫也會存在,只是不會顯示
class Count {
  constructor() {
  
  }
}

定義 class 之後,可以透過 new 生成實例

class Count {
  constructor(x, y) {
      this.x = x
      this.y = y
  }
  todoString () {
      return this.x + this.y
  }
}

//生成實例
const a = new Count(1, 2)

上面 class 的寫法實際上等同於下面 ES5 的寫法

function Count(x, y) {
    this.x = x
    this.y = y
}

Count.prototype.todoString = function () {
    return this.x + this.y
}

var a = new Count(1, 2)

定義 class 屬性

要在 class 裡面定義屬性,必須在構造函數中去宣告,定義函數也是。

class Profile {
    constructor () {
        this.state = {
            name: null
        }
        this.getName = this.getName.bind()
    }
    getName () {
        //...
    }
}

class properties proposal

上述定義 class 屬性的方式比較麻煩,所以 ES7 推出了另一個定義方法,class properties proposal,可以省略 constructor,在 class 內直接定義屬性

class Profile {
    state = {
        name: null
    }
    getName () {
        //...
    }
}

class properties proposal 在 react 中的應用

class Profile extends Component {
    state = {
        name: leo,
        age: 29,
        gender: male
    }
    render () {
        const {name, age, gender} = this.state
        return <div>
            {name}, 今年 {age}
        </div>
    }

使用 static 定義靜態方法和靜態屬性

使用 static 定義 class 的靜態方法,不需要實例化也能訪問

class Profile {
    static getName (name) {
        return name
    }
    static gender = 'male'
}

const P = Profile.getName('ben') //不需要實例化就能使用
const gender = Profile.gender

class 的繼承

class 可以透過 extends 來繼承,比 ES5 透過原型鍊修改來繼承更為方便易懂。會在 constructor 透過一個叫 super 的 function 去實現繼承。super 是調用父 class,但它的 this 則指向子 class,必須在使用 super 後才能使用 this。

class A {}

class B extends A { //繼承 A
    constructor () {
        console.log(this) // 報錯
        super ()//用來實現繼承的內建方法
        console.log(this) // 正確
    }

}

class properties proposal 中會自動綁定繼承,所以一樣可以省略 super

class A {
    state = {
        age: 30
    };
};

class B extends A { //繼承 A
    state = {
        userAge = this.state.age // age 已經被繼承,可以直接訪問, this 指向 B
    };
};

const P = new B() // 實例化
console.log(P.state.userAge) //30

class 修飾器 Decorator

Decorator 是 ES7 新增的一個特性,主要用於 class 的行為,只能用於 class 和 class 的方法,不能用於函式。
Decorator 實際上是一個函式,接受 class 作為參數,如下

function annotation (target) {
    target.annotated = true; //給 target class 增加 annotated 的屬性
    target.state = { //給 target class 增加 state 物件
        name: 'leo'
    };
};

// 使用修飾器時要放在 class 的頂部,或是類的方法的頂部
@annotation
class Profile {

    @annotation //也可以用於修改 class 的方法
    getName(name) {
        return name;
    };
};

// 可以調用到新的屬性
console.log(Profile.annotated);
console.log(Profile.state);

附帶一提,decorator 需要 babel 插件的支持,create-react-app,本身支持。
@babel/plugin-proposal-decorators

修飾器在 react 中的運用

這邊課程中以 mobx 為例,mobx 是 react 中常用的資料狀態管理方法之一,它應用了 decorator 來結合 store 和元件,範例如下

import React, { Component } from 'react';
// inject, observer 都是 mobx 本身封裝的修飾器
import { inject, observer } from 'mobox-react';

@inject('store') //傳入 store
@observer //觀察元件狀態的變更
class SchoolComponent extends Component {
    state = {
        schoolName: this.props.store.school.name // store 是透過修飾器傳入
    }
    
    render () {
        return (
        <div>學校:{this.state.schoolName}</div>
        )
    }
}

課程中建議不要大量使用 decorator,因為隨著 react hook 的推出,很多開發者更傾向於函式組件的寫法,而 decotator 主要應用於 class,因此往後的使用將會慢慢減少。

小結

今天整理了一直以來不大清楚的 class 和 decorator,下一篇會是最後一篇和 ES6 相關,是整理我看過很多次,觀念上卻還是常常混淆不清的 promise 以及 await async。


上一篇
【Day 3】React 中常用的一些 ES6 語法 (一)
下一篇
【Day 5】React 中常用的一些 ES6 語法 (三)
系列文
React 30 天學習歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言