イベント処理
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
以降の追加の引数は自動的に転送される