在 React 中何時使用箭頭函數

當咱們想起箭頭函數時,腦海裏可能會浮現 簡潔有趣 等形容詞,其實,咱們存在一些 更充分的理由 使咱們在聯想起 箭頭函數 時不得不想到的react

圖片描述

解決 this 引發的問題

箭頭函數不會在函數體內從新定義 this 的值,這使得在回調中的行爲更容易預測,而且避免了 this 在回調中潛存的 bug瀏覽器

下面咱們來看一個 exampleapp

咱們指望點擊按鈕,改變按鈕顏色,代碼以下函數

class BrokenButton extends React.Component {
  render() {
    return (
      <button onClick={this.handleClick} style={this.state}>
        Set background to red
      </button>
    );
  }

  handleClick() {
    this.setState({ backgroundColor: "red" });
  }
}

render(<BrokenButton />, document.getElementById("root"));

然而,當咱們點擊按鈕時,什麼效果都沒有,爲何會這樣呢性能

其實,不是 handleClick 方法沒有起做用,由於 JavaScript 中壓根沒有方法, JavaScript 中只有函數,而函數中的 this 存在一些規則,正是這些規則,讓上面的 handleClick 中的 this 值變成了 null優化

你須要清楚明白的是: 你沒法肯定一個方法函數中 this 的指向,由於它的值跟函數的調用方式有關this

除非,你使用 箭頭函數,由於箭頭函數中 this 的值是繼承自 外圍做用域spa

class Button extends React.Component {
  render() {
    return (
      <button
        onClick={() => this.setState({ backgroundColor: "red" })}
        style={this.state}
      >
        Set background to red
      </button>
    );
  }
}

render(<Button />, document.getElementById("root"));

如今就對了,接下來,咱們繼續調試

瀏覽器支持

瀏覽器對 箭頭函數 的支持大概是 73%,由於目前,IE 並不支持。但若是你已經意識到這一點,而且你還會代碼轉譯,這對你來講就不算什麼問題code

性能問題

你們都發現了,箭頭函數 書寫起來是很是容易的,但書寫忒多的函數,也會形成一些問題

定義函數是昂貴的

瀏覽器每執行一次 =>,就須要建立一個 新的函數對象,這實際上是一個比較 昂貴 的操做

固然,若是你不是想構建一個 性能超級無敵宇宙螺旋棒 的組件,渲染一個 很是長 的列表或 很是大 的表格,你也不會發現這是一個 問題

因此,若是你的組件只是在頁面中渲染個幾回,你也 不必忒擔憂 性能這方面的問題

兩個相同的箭頭函數並不相等

爲了讓你們意識到這個問題,接下來,咱們用 == 比較一下兩個相同的箭頭函數相不相等

const a = x => x,
      b = x => x;

render(
  <div>
    <h3>
      Are <code>a</code> and <code>b</code> equal by <code>==</code>?
    </h3>
    <p>
      {a == b ? "Yes!" : "No :("}
    </p>
  </div>,
  document.getElementById("root")
);

若是你在 render 中使用箭頭函數,那麼你在每次調用 render 時都會去建立一個新的函數對象,此時,即便使用 PureComponentshouldComponentUpdate 也起不到優化做用

你能夠在下面實例中看清這一點,其中,<PropChangeCounter /> 組件用於打印 props 改變的次數

import PropChangeCounter from "react-armory-prop-change-counter";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { email: "" };
  }
  render() {
    return (
      <div>
        <input
          placeholder="Email"
          value={this.state.email}
          onChange={e => this.setState({ email: e.target.value })}
        />
        <PropChangeCounter
          constant={"this doesn't change"}
          value={this.state.email}
          onChange={e => this.setState({ email: e.target.value })}
        />
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

只定義一次

若是你以爲 性能 對你的組件很重要,那麼你確定會想若是在組件中只定義箭頭函數 一次 該有多好

其中一種實現方式是在 constructor 中使用箭頭函數,固然,對於複雜些的組價來講,這會變的很笨拙

若是你使用了 Babelcreate-react-app 構建你的應用,你能夠將箭頭函數設置爲 class fieldsarrow function methods

以下,你能夠將 handleClick 從新定義爲一個 arrow function method,來修復第一個 example 中的 bug

class Button extends React.Component {
  render() {
    return (
      <button onClick={this.handleClick} style={this.state}>
        Set background to red
      </button>
    );
  }

  // Note: this syntax is not yet part of JavaScript proper, but is slated
  // for inclusion in the next version. It should already work with Babel.
  handleClick = () => {
    this.setState({ backgroundColor: "red" });
  };
}

總結

  • 若是 環境支持 箭頭函數,那麼鼓勵使用

  • 儘可能避免對 React 組件 使用箭頭函數,它會使 調試 變的困難

  • 若是有須要,能夠在 render 中使用箭頭函數

  • 性能 着想,避免在 render 中使用大量函數

原文連接:When should I use Arrow Functions? (James K Nelson)

相關文章
相關標籤/搜索