最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

為什么this會(huì)是undefined

初學(xué)React類組件時(shí),最不爽的一點(diǎn)應(yīng)該就是 this 指向問題了吧!初識(shí)React的時(shí)候,肯定寫過這樣錯(cuò)誤的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 時(shí),就會(huì)如期遇到如下的錯(cuò)誤...

?? this 丟失了。編譯React類組件時(shí),會(huì)將 jsx 轉(zhuǎn)成 React.createElement,并onClick 事件用對(duì)象包裹一層傳參給該函數(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;

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

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

經(jīng)受過面向?qū)ο缶幊痰南炊Y,為什么還要在類中手動(dòng)綁定 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 方法)時(shí),this 變成了 undefined。寫到這里可能有人會(huì)提出疑問,就算不是類的實(shí)例調(diào)用的 logThis 方法,那 this 也應(yīng)該是 window 對(duì)象。

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

所以,在非React類組件內(nèi),有時(shí)候也得手動(dòng)綁定 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 // 通過 `方法裝飾器` 自動(dòng)綁定this
  handleClick() {
    this.setState({ a: 2 });
  }
  render() {
    return <div onClick={this.handleClick}>{this.state.a}</div>;
  }
}

對(duì)于 方法裝飾器,該函數(shù)對(duì)應(yīng)三個(gè)入?yún)ⅲ来问?/p>

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

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

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

descriptor 屬性描述器

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

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

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

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

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

其中,

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

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

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

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

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

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

既然 get 函數(shù)有機(jī)會(huì)傳入 this 對(duì)象,我們就從這里入手,通過 @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~~~

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

參考

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

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

相關(guān)文章

  • react quill中圖片上傳由默認(rèn)轉(zhuǎn)成base64改成上傳到服務(wù)器的方法

    react quill中圖片上傳由默認(rèn)轉(zhuǎn)成base64改成上傳到服務(wù)器的方法

    這篇文章主要介紹了react quill中圖片上傳由默認(rèn)轉(zhuǎn)成base64改成上傳到服務(wù)器的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • React插槽使用方法

    React插槽使用方法

    本文主要介紹了React插槽使用方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • ReactNative錯(cuò)誤采集原理在Android中實(shí)現(xiàn)詳解

    ReactNative錯(cuò)誤采集原理在Android中實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了ReactNative錯(cuò)誤采集原理在Android中實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • react中braft-editor的基本使用方式

    react中braft-editor的基本使用方式

    這篇文章主要介紹了react中braft-editor的基本使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • React使用Props實(shí)現(xiàn)父組件向子組件傳值

    React使用Props實(shí)現(xiàn)父組件向子組件傳值

    在React中,組件之間的數(shù)據(jù)傳遞通常是通過屬性(Props)來實(shí)現(xiàn)的,父組件可以通過屬性向子組件傳遞數(shù)據(jù),這是React組件通信的基礎(chǔ)模式之一,本文將探討如何使用Props來實(shí)現(xiàn)父組件向子組件傳遞數(shù)據(jù),需要的朋友可以參考下
    2025-04-04
  • 在React中引入Tailwind?CSS的完整指南

    在React中引入Tailwind?CSS的完整指南

    在現(xiàn)代前端開發(fā)中,使用?UI?庫可以顯著提高開發(fā)效率,Tailwind?CSS?是一個(gè)功能類優(yōu)先的?CSS?框架,本文將詳細(xì)介紹如何在?React?項(xiàng)目中引入和使用?Tailwind?CSS,包括各種配置選項(xiàng)和最佳實(shí)踐,需要的朋友可以參考下
    2025-04-04
  • react如何修改循環(huán)數(shù)組對(duì)象的數(shù)據(jù)

    react如何修改循環(huán)數(shù)組對(duì)象的數(shù)據(jù)

    這篇文章主要介紹了react如何修改循環(huán)數(shù)組對(duì)象的數(shù)據(jù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • React?Hook?Form?優(yōu)雅處理表單使用指南

    React?Hook?Form?優(yōu)雅處理表單使用指南

    這篇文章主要為大家介紹了React?Hook?Form?優(yōu)雅處理表單使用指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • React組件化學(xué)習(xí)入門教程講解

    React組件化學(xué)習(xí)入門教程講解

    React是現(xiàn)在前端使用頻率最高的三大框架之一,React率先提出虛擬DOM的思想和實(shí)現(xiàn),使其保持有良好的性能。本篇文章將對(duì)React組件化的入門學(xué)習(xí)進(jìn)行講解,同時(shí)針對(duì)模塊化的思想進(jìn)行概述,為接下來組件化開發(fā)的文章進(jìn)行知識(shí)儲(chǔ)備
    2022-09-09
  • react中使用better-scroll滾動(dòng)插件的實(shí)現(xiàn)示例

    react中使用better-scroll滾動(dòng)插件的實(shí)現(xiàn)示例

    滾動(dòng)在很多地方都可以使用,本文主要介紹了react中使用better-scroll滾動(dòng)插件的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07

最新評(píng)論

信丰县| 北辰区| SHOW| 厦门市| 德钦县| 霍林郭勒市| 潢川县| 金寨县| 荣昌县| 左贡县| 舟山市| 高平市| 宾川县| 晋中市| 汉川市| 和硕县| 石城县| 阿拉尔市| 曲阜市| 博乐市| 丰原市| 丰镇市| 彭泽县| 孟津县| 铁岭市| 万安县| 岗巴县| 靖边县| 平罗县| 得荣县| 平和县| 溆浦县| 无棣县| 云安县| 开封县| 四川省| 陵川县| 宁远县| 万荣县| 彰化市| 古交市|