欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

TS裝飾器bindThis優(yōu)雅實(shí)現(xiàn)React類組件中this綁定

 更新時間:2022年11月27日 17:17:12   作者:RyanOnCloud  
這篇文章主要為大家介紹了TS裝飾器bindThis優(yōu)雅實(shí)現(xiàn)React類組件中this綁定,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

為什么this會是undefined

初學(xué)React類組件時,最不爽的一點(diǎn)應(yīng)該就是 this 指向問題了吧!初識React的時候,肯定寫過這樣錯誤的demo。

import React from 'react';
export class ReactTestClass extends React.Component {
  constructor(props) {
    super(props);
    this.state = { a: 1 };
  }
  handleClick() {
    this.setState({a: 2})
  }
  render() {
    return <div onClick={this.handleClick}>{this.state.a}</div>;
  }
}

上面的代碼在執(zhí)行 onClick 時,就會如期遇到如下的錯誤...

?? this 丟失了。編譯React類組件時,會將 jsx 轉(zhuǎn)成 React.createElement,并onClick 事件用對象包裹一層傳參給該函數(shù)。

// 編譯后的結(jié)果
class ReactTestClass extends _react.default.Component {
  constructor(props) {
    super(props);
    this.state = {
      a: 1
    };
  }
  handleClick() {
    this.setState({
      a: 2
    });
  }
  render() {
    return /*#__PURE__*/ _react.default.createElement(
      "div",
      {
        onClick: this.handleClick // ? 鬼在這里
      },
      this.state.a
    );
  }
}
exports.ReactTestClass = ReactTestClass;

寫到這里肯定會讓大家覺得是 React 在埋坑,其實(shí)不然,官方文檔有澄清:

這并不是 React 自身的行為: 這是因?yàn)?函數(shù)在 JS 中就是這么工作的。通常情況下,比如 onClick={this.handleClick} ,你應(yīng)該 bind 這個方法。

經(jīng)受過面向?qū)ο缶幊痰南炊Y,為什么還要在類中手動綁定 this? 我們參考如下代碼

class TestComponent {
    logThis () {
        console.log(this); // 這里的 `this` 指向誰?
    }
    privateExecute (cb) {
         cb();
    }
    execute () {
        this.privateExecute(this.logThis); // 正確的情況應(yīng)該傳入 this.logThis.bind(this)
    }
}
const instance = new TestComponent();
instance.execute();

上述代碼如期打印了 undefined。就是在 privateRender 中執(zhí)行回調(diào)函數(shù)(執(zhí)行的是 logThis 方法)時,this 變成了 undefined。寫到這里可能有人會提出疑問,就算不是類的實(shí)例調(diào)用的 logThis 方法,那 this 也應(yīng)該是 window 對象。

沒錯!在非嚴(yán)格模式下,就是 window 對象,但是(知識點(diǎn)) 使用了 ES6 的 class 語法,所有在 class 中聲明的方法都會自動地使用嚴(yán)格模式,故 this 就是 undefined。

所以,在非React類組件內(nèi),有時候也得手動綁定 this。

優(yōu)雅的@bindThis

使用 .bind(this)

render() {
    return <div onClick={this.handleClick.bind(this)}>{this.state.a}</div>;
}

或箭頭函數(shù)

handleClick = () => {
    this.setState({a: 2})
}

都可以完美解決,但是早已習(xí)慣面向?qū)ο蠛拖矚g搞事情的我總覺得處理的不夠優(yōu)雅而大方。最終期望綁定this的方式如下,

import React from 'react';
import { bindThis } from './bind-this';
export class ReactTestClass extends React.Component {
  constructor(props) {
    super(props);
    this.state = { a: 1 };
  }
  @bindThis // 通過 `方法裝飾器` 自動綁定this
  handleClick() {
    this.setState({ a: 2 });
  }
  render() {
    return <div onClick={this.handleClick}>{this.state.a}</div>;
  }
}

對于 方法裝飾器,該函數(shù)對應(yīng)三個入?yún)?,依次?/p>

export function bindThis(
    target: Object, 
    propertyKey: string, 
    descriptor: PropertyDescriptor,
) {
    // 如果要返回值,應(yīng)返回一個新的屬性描述器
}

target 對應(yīng)的是類的 prototype

propertyKey 對應(yīng)的是方法名稱,字符串類型,例如 "handleClick"

descriptor 屬性描述器

對于 descriptor 能會比較陌生,當(dāng)前該屬性打印出來的結(jié)果是,

{
  value: [Function: handleClick],
  writable: true,
  enumerable: false,
  configurable: true
}

參看 MDN 上的 Object.defineProperty,我們發(fā)現(xiàn)對于屬性描述器一共分成兩種,data descriptoraccessor descriptor,兩者的區(qū)別主要在內(nèi)在屬性字段上:

configurableenumerablevaluewritablegetset
data descriptor??????
accessor descriptor??????

? 可以存在的屬性,? 不能包含的屬性

其中,

configurable,表示兩種屬性描述器能否轉(zhuǎn)換、屬性能否被刪除等,默認(rèn) false

enumerable,表示是否是可枚舉屬性,默認(rèn) false

value,表示當(dāng)前屬性值,對于類中 handleClick 函數(shù),value就是該函數(shù)本身

writable,表示當(dāng)前屬性值能否被修改

get,屬性的 getter 函數(shù)。當(dāng)訪問該屬性時,會調(diào)用此函數(shù)。執(zhí)行時不傳入任何參數(shù),但是會傳入 this 對象(由于繼承關(guān)系,這里的this并不一定是定義該屬性的對象)

set,屬性的 setter 函數(shù)。當(dāng)屬性值被修改時,會調(diào)用此函數(shù)。該方法接受一個參數(shù)(也就是被賦予的新值),會傳入賦值時的 this 對象。

既然 get 函數(shù)有機(jī)會傳入 this 對象,我們就從這里入手,通過 @bindThis 裝飾器給 handleClick 函數(shù)綁定真正的 this

export function bindThis(
    target: Object, 
    propertyKey: string, 
    descriptor: PropertyDescriptor,
) {
    const fn = descriptor.value; // 先拿到函數(shù)本身
    return {
        configurable: true,
        get() {
            const bound = fn.bind(this); // 這里的 this 是當(dāng)前類的示例
            return bound;
        }
    }
}

bingo~~~

一個優(yōu)雅又不失功能的 @bindThis 裝飾器就這么愉快地搞定了。

參考

考慮邊界條件更為詳細(xì)的 @bindThis 版本可參考:autobind-decorator

以上就是TS裝飾器bindThis優(yōu)雅實(shí)現(xiàn)React類組件中this綁定的詳細(xì)內(nèi)容,更多關(guān)于React類組件this綁定的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React?Native?中實(shí)現(xiàn)倒計(jì)時功能

    React?Native?中實(shí)現(xiàn)倒計(jì)時功能

    這篇文章主要介紹了React?Native中實(shí)現(xiàn)倒計(jì)時功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • React如何優(yōu)雅的捕獲異常

    React如何優(yōu)雅的捕獲異常

    捕獲異常是來定位你錯誤代碼的。本文主要介紹了 React如何捕獲異常,你知道多少種方法,ErrorBoundary,ErrorBoundary-try-catch等等。本文就來詳細(xì)的介紹一下
    2021-06-06
  • React Native 啟動流程詳細(xì)解析

    React Native 啟動流程詳細(xì)解析

    這篇文章主要介紹了React Native 啟動流程簡析,文以 react-native-cli 創(chuàng)建的示例工程(安卓部分)為例,給大家分析 React Native 的啟動流程,需要的朋友可以參考下
    2021-08-08
  • React Navigation 路由傳參的操作代碼

    React Navigation 路由傳參的操作代碼

    這篇文章主要介紹了React Navigation 路由傳參,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • React中setState/useState的使用方法詳細(xì)介紹

    React中setState/useState的使用方法詳細(xì)介紹

    這篇文章主要介紹了React中setState/useState的使用方法,useState 和 setState 在React開發(fā)過程中 使用很頻繁,但很多人都停留在簡單的使用階段,并沒有正在了解它們的執(zhí)行機(jī)制
    2023-04-04
  • React國際化react-i18next詳解

    React國際化react-i18next詳解

    react-i18next 是基于 i18next 的一款強(qiáng)大的國際化框架,可以用于 react 和 react-native 應(yīng)用,是目前非常主流的國際化解決方案。這篇文章主要介紹了React國際化react-i18next的相關(guān)知識,需要的朋友可以參考下
    2021-10-10
  • react.js使用webpack搭配環(huán)境的入門教程

    react.js使用webpack搭配環(huán)境的入門教程

    本文主要介紹了react 使用webpack搭配環(huán)境的入門教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-08-08
  • 如何對react hooks進(jìn)行單元測試的方法

    如何對react hooks進(jìn)行單元測試的方法

    這篇文章主要介紹了如何對react hooks進(jìn)行單元測試的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • react-native彈窗封裝的方法

    react-native彈窗封裝的方法

    這篇文章主要為大家詳細(xì)介紹了react-native彈窗封裝的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • react-router中<Link/>的屬性詳解

    react-router中<Link/>的屬性詳解

    這篇文章主要給大家介紹了關(guān)于react-router中<Link/>屬性的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-06-06

最新評論