tanish-kr's learning log

Learning output log

JavaScript React

イベント処理

Reactのイベント処理はDOM要素のイベント処理と非常に似ているが、文法的な違いがある

  • htmlの場合
<button onclick="action()">
  action
</button>
<button onClick={action}>
  action
</button>

イベントの動作を抑止する

Reactではfalseを返してもデフォルトの動作を抑止することは出来ません。明示的にpreventDefaultを呼び出す必要があります。

function ActionLink() {
  /*
   * eは合成(synthetic)イベントであり、W3Cの仕様に沿って定義しているので、
   * ブラウザ間の互換性を気にする必要はない
   */
  function handleClick(e) {
    e.preventDefault();
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

Reactを使う場合、addEventListenerを呼び出してリスナーを追加するべきではない。 代わりに要素が最初にレンダリングされる際にリスナーを指定するようにしてください。

thisの扱い

関数内でthisが使用されている場合、bindする必要がある。

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? "ON" : "OFF"}
      </button>
    );
  }
}

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

bindを使用しないパターン

  • パブリッククラスフィールドを使用する
class LogginButton extends React.Component {
  handleClick = () => {
    console.log("this is: ", this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}
  • アロー関数を使用する
class LogginButton extends React.Component {
  handleClick() {
    console.log("this is: ", this);
  }

  render() {
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}

上記の場合、LogginButtonがレンダリングされるたびに異なるコールバック関数が毎回作成される問題がある。 このコールバックがpropsの一部として下層のコンポーネントに渡される場合、それら下層コンポーネントが余分に再描画されることになり、パフォーマンスが悪くなるので、一般的にはコンストラクタでバインドするか、クラスフィールド構文を使用して、この種のパフォーマンスの問題を避けるようにしたほうが良い

イベントバンドらに引数を渡す

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

アロー関数ではeを明示的に渡す必要があるが、bindの場合にはid以降の追加の引数は自動的に転送される