国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

React Bind Handle的思考

UnixAgain / 2396人閱讀

摘要:更加需要注意的東西是無法繼承帶來的性能問題。看起來的確是還不錯(cuò)。表示不需要自動(dòng)綁定的函數(shù)的名字。并且并沒有成為標(biāo)準(zhǔn),但是其實(shí)也差不多了,并不擔(dān)心。結(jié)語這里的所有的解決思路都各有千秋吧。

文章來自我個(gè)人的Github
)

在平時(shí)的開發(fā)里面,總會(huì)碰到handle綁定的問題。如果你和我一樣懶或者思考過,你會(huì)覺得這個(gè)過程實(shí)在是太煩了吧。這里記錄一下我的思路和歷程。

這里以一個(gè)按鈕的點(diǎn)擊事件來做示例。

class App extends React.Components {
    state = {
        count: 0
    }

    clickHandler () {
        const count = this.state.count + 1
        this.setState({ count })
    }

    render() {
         return (
            
        )
    }
}

這個(gè)例子的目的是點(diǎn)擊按鈕觸發(fā)clickHandler來讓計(jì)數(shù)器加1。我們可以用兩種不同的方式來觸發(fā)這個(gè)handle,因?yàn)槲覀兪褂昧?b>this.setState,所以我們都必須要給函數(shù)綁定this。亦或是使用箭頭函數(shù)處理這個(gè)地方。

直接在jsx里面bind(this)

嗯 這個(gè)的確可以。但是寫起來非常的長(zhǎng)看起來也挺丑的。有個(gè)問題是每次重渲染的時(shí)候都會(huì)重新bind一次函數(shù),對(duì)于比較大的列表來說這個(gè)地方非常不可取。

使用箭頭函數(shù)

clickHandler改成如下的范式。

clickHandler = () => {
    const count = this.state.count + 1
    this.setState({ count })
}

// render ...

誒這樣看起來會(huì)好很多誒。但是如果你有強(qiáng)迫癥你會(huì)發(fā)現(xiàn)一件事情。如果我們加上生命周期函數(shù)和一些其他的handler ... 比如這樣。

componentDidMount () {}
componentWillMount () {}
componentWillUpdate () {}

clickHandler = () => {
    const count = this.state.count + 1
    this.setState({ count })
}

antoherHandle = () => {}

你會(huì)發(fā)現(xiàn)這里生命周期函數(shù)和handler的寫法不一樣。但是你的確可以讓它們變得一樣,比如把生命周期函數(shù)改成箭頭函數(shù)??墒沁@看起來不會(huì)覺得很怪異嗎。畢竟你一直以來都不是這么做的。

除此之外箭頭函數(shù)無法被繼承,這意味著如果你的子組件需要繼承函數(shù),這將會(huì)導(dǎo)致無法做到。更加需要注意的東西是無法繼承帶來的性能問題。這會(huì)導(dǎo)致每次創(chuàng)建組件都會(huì)創(chuàng)建新的方法導(dǎo)致額外的開銷(因?yàn)榧^函數(shù)的實(shí)現(xiàn)其實(shí)是直接在constructor函數(shù)里丟方法),如果是通過繼承,那么它們這些方法總是來自同一個(gè)prototype,js編譯器是會(huì)做優(yōu)化的。

詳細(xì)文章可以看這一篇Arrow Functions in Class Properties Might Not Be As Great As We Think。

在構(gòu)造器里面使用bind(this)

通過構(gòu)造器來寫綁定函數(shù)其實(shí)看起來是不錯(cuò)的

constructor (props) {
    super(props)
    this.clickHandler = this.clickHandler.bind(this)
    this.antoherHandle = this.antoherHandle.bind(this)
}

既解決了性能(內(nèi)存)的問題。還能做很多有意思的事情比如說,利用現(xiàn)有的方法添加更有語義化的方法。

constructor (props) {
    super(props)
    this.clickHandler = this.clickHandler.bind(this)
    this.antoherHandle = this.antoherHandle.bind(this)
    this.clickWithOne = this.clickHandler.bind(this, 1)
}

這樣就能產(chǎn)生每次都會(huì)傳參數(shù)1的新事件??雌饋淼拇_是還不錯(cuò)。但是仍然有問題。當(dāng)你的方法線性的增加的時(shí)候,如果有三個(gè)四個(gè)五個(gè)六個(gè)的時(shí)候,你可能需要一個(gè)一個(gè)的綁定。添加它們到構(gòu)造函數(shù)里面,更糟糕的可能是通過復(fù)制粘貼以前寫的方法,你會(huì)綁定錯(cuò)誤的函數(shù)。就像這樣。

constructor (props) {
    super(props)
    this.clickHandler = this.clickHandler.bind(this)
    this.antoherHandle = this.antoherHandle.bind(this)
    this.clickWithOne = this.antoherHandle.bind(this, 1)
}

你必須在運(yùn)行的時(shí)候才知道你的clickWithOne綁定的其實(shí)是antoherHandle。如果你沒測(cè)試過,那么很可能就會(huì)出現(xiàn)一些你難以理解的問題或者bug。

自動(dòng)綁定

如果你動(dòng)腦想想會(huì)發(fā)現(xiàn)可以寫一個(gè)autobind的方法來自綁定函數(shù)呀。但是你很懶沒有去寫,你通過github搜索到了一個(gè)叫做React-autobind的庫(kù)??雌饋砗孟襁€不錯(cuò)。

constructor(props) {
  super(props);
  autoBind(this);
}

甚至可以不綁定某些方法。

constructor(props) {
  super(props);
  autoBind(this, {
    wontBind: ["leaveAlone1", "leaveAlone2"]
  });
}

或者指定只綁定某些方法。

constructor(props) {
  super(props);
  autoBind(this, {
    bindOnly: ["myMethod1", "myMethod2"]
  });
}

看起來似乎是妙極了。但是你會(huì)發(fā)現(xiàn)這個(gè)寫法其實(shí)還是很繁瑣啊。要寫一坨東西。。打開源碼看一眼你會(huì)發(fā)現(xiàn)有一個(gè)默認(rèn)的wonbind列表。

let wontBind = [
  "constructor",
  "render",
  "componentWillMount",
  "componentDidMount",
  "componentWillReceiveProps",
  "shouldComponentUpdate",
  "componentWillUpdate",
  "componentDidUpdate",
  "componentWillUnmount"
];

表示不需要自動(dòng)綁定的函數(shù)的名字。但是這個(gè)列表非常的糟糕,因?yàn)殡S著React版本的提升,某些鉤子和方法都會(huì)被廢棄,隨著時(shí)間可能還會(huì)增加增多的方法。

這個(gè)庫(kù)也很久沒更新了。差評(píng)還是放棄吧。。。

Autobind-decorator

如果你了解過ES7decorator。你會(huì)發(fā)現(xiàn)上面的寫法完全可以使用decorator的形式表示,并且這個(gè)庫(kù)也支持在typescript上面使用。并且結(jié)構(gòu)會(huì)非常的清晰。于是你找到了autobind-decorator這個(gè)庫(kù)。它能幫助到我們,給我們想要的東西,文檔一開始就告訴我們。

// Before:


// After:

用之前...用之后的樣子,很好就是我們要的。 這個(gè)庫(kù)有個(gè)缺點(diǎn)就是必須的IE11+以上的版本才支持,但是這其實(shí)也還好。

另外就是你的開啟decorator的支持在babel的配置里面。

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
  ]
}

我們來看看推薦的用法。

import {boundMethod} from "autobind-decorator"

class Component {
  constructor(value) {
    this.value = value
  }

  @boundMethod
  method() {
    return this.value
  }
}

let component = new Component(42)
let method = component.method // .bind(component) isn"t needed!
method() // returns 42

給方法綁定this,而不是整個(gè)類,這么做是更加合理的。因?yàn)椴皇敲總€(gè)方法都需要用到this的。如Dan所說。

It is unnecessary to do that to every function. This is just as bad as autobinding (on a class). You only need to bind functions that you pass around. e.g. onClick={this.doSomething}. Or fetch.then(this.handleDone) -- Dan Abramov?

既可以在函數(shù)上,也可以在類上使用的@autobind。

import autobind from "autobind-decorator"

class Component {
  constructor(value) {
    this.value = value
  }

  @autobind
  method() {
    return this.value
  }
}

let component = new Component(42)
let method = component.method // .bind(component) isn"t needed!
method() // returns 42

// Also usable on the class to bind all methods
// Please see performance if you decide to autobind your class
@autobind
class Component { }

只能作用于類的@boundClass,我們難免也會(huì)有全都需要綁定到this的情況這時(shí)候我們直接boundClass會(huì)更加的簡(jiǎn)潔。

import {boundClass} from "autobind-decorator"

@boundClass
class Component {
  constructor(value) {
    this.value = value
  }

  method() {
    return this.value
  }
}

let component = new Component(42)
let method = component.method // .bind(component) isn"t needed!
method() // returns 42

缺點(diǎn)也是有的,并不能像constructor那樣自己隨隨便便的定不同的方法名通過原有的方法,必須的寫出一個(gè)新的,但是這是小問題,無傷大雅。并且descorator并沒有成為標(biāo)準(zhǔn),但是其實(shí)也差不多了,并不擔(dān)心。

結(jié)語

這里的所有的解決思路都各有千秋吧。怎么取舍還是看自己,這里就不一一列出來各自的對(duì)比了 ,于我個(gè)人而言會(huì)偏好Autobind-decorator,認(rèn)為這是所有解決方案里面最好的一個(gè)了,但是要引入一個(gè)額外的依賴還是有點(diǎn)麻煩。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/109286.html

相關(guān)文章

  • 為什么會(huì)出現(xiàn)React Hooks?

    摘要:盡管已經(jīng)受到高度贊揚(yáng),團(tuán)隊(duì)仍然認(rèn)為有必要構(gòu)建和發(fā)布。用來描述組件的所有信息都將作為對(duì)象傳遞給。這是一個(gè)巨大的勝利,因?yàn)樗玫嘏c標(biāo)準(zhǔn)保持一致。 showImg(https://segmentfault.com/img/bVbvYyy?w=880&h=369); 原文:https://dev.to/tylermcginnis/why-react-hooks-51lj.... 譯者:前端...

    longshengwang 評(píng)論0 收藏0
  • VUE防抖與節(jié)流最佳解決方案——函數(shù)式組件

    摘要:案例持續(xù)觸發(fā)事件時(shí),并不立即執(zhí)行函數(shù),當(dāng)毫秒內(nèi)沒有觸發(fā)事件時(shí),才會(huì)延時(shí)觸發(fā)一次函數(shù)。也以函數(shù)形式暴露普通插槽。這樣的場(chǎng)景組件用函數(shù)式組件是非常方便的。相關(guān)閱讀函數(shù)式組件自定義指令前言 有echarts使用經(jīng)驗(yàn)的同學(xué)可能遇到過這樣的場(chǎng)景,在window.onresize事件回調(diào)里觸發(fā)echartsBox.resize()方法來達(dá)到重繪的目的,resize事件是連續(xù)觸發(fā)的這意味著echarts...

    OldPanda 評(píng)論0 收藏0
  • React模式【譯】

    摘要:檢查空值不要去檢查是否存在某個(gè)值,快使用。當(dāng)你的值是對(duì)象或者數(shù)組時(shí),使用聲明嵌套數(shù)據(jù)的預(yù)期類型。命名事件可以使用自定義事件替代預(yù)設(shè)的事件名。 原文:react-patterns 代碼結(jié)構(gòu) class definition constructor event handlers component lifecycle getters render defaultProps p...

    BicycleWarrior 評(píng)論0 收藏0
  • React事件

    摘要:在中使用原生事件在中使用原生事件級(jí)事件和。的合成事件實(shí)現(xiàn)中,僅僅對(duì)最外層容器進(jìn)行綁定,并且依賴事件冒泡完成事件委派,避免了事件捕獲的瀏覽器不兼容特性。 Event Handler ----React事件 React中的事件包括合成事件和原生事件,React底層對(duì)合成事件進(jìn)行事件委派和手動(dòng)綁定,原生事件的使用在高程3有具體講解,難點(diǎn)在于跨瀏覽器兼容和DOM0/DOM2級(jí)事件處理程序的使用...

    hearaway 評(píng)論0 收藏0
  • React事件

    摘要:在中使用原生事件在中使用原生事件級(jí)事件和。的合成事件實(shí)現(xiàn)中,僅僅對(duì)最外層容器進(jìn)行綁定,并且依賴事件冒泡完成事件委派,避免了事件捕獲的瀏覽器不兼容特性。 Event Handler ----React事件 React中的事件包括合成事件和原生事件,React底層對(duì)合成事件進(jìn)行事件委派和手動(dòng)綁定,原生事件的使用在高程3有具體講解,難點(diǎn)在于跨瀏覽器兼容和DOM0/DOM2級(jí)事件處理程序的使用...

    Cciradih 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

UnixAgain

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<