LoginFormコンポーネントがあります。送信前に、loginName
とpassword
の両方が設定されていることを確認したい。私はこのコードで試しました(多くのものは省略されました):
class LoginForm extends Component {
constructor() {
super();
this.state = {
error: "",
loginName: "",
password: "",
remember: true
};
}
submit(e) {
e.preventDefault();
if(!this.state.loginName || !this.state.password) { //this is null
this.setState({ error: "Fill in both fields" });
} else {
console.log("submitting form");
}
}
render() {
return (
<div className="col-xs-12 col-sm-6 col-md-4">
<form className="login" onSubmit={this.submit}>
<button type="submit" className="btn btn-default">Sign in</button>
</form>
</div>
);
}
}
export default LoginForm;
ただし、イベントハンドラーでTypeError
がnullであることを示すthis
を取得します。
私は何をすべきですか?
this
はsubmit
であるため、this
メソッドにundefined
を設定する必要があります。この操作には.bind
onSubmit={ this.submit.bind(this) }
または、 arrow function を使用できます
onSubmit={ (e) => this.submit(e) }
Reactは以前、コールバックをこれにバインドしていました。しかし、今ではなくなっており、自分でバインドするか、ラッパーを作成する必要があります
onSubmit={() => this.submit()}
Babelを使用している場合は、 バインド演算子 と transform-function-bind プラグインを使用できます。
onSubmit={::this.submit}
これは、次の構文糖衣です。
onSubmit={this.submit.bind(this)}
this
をクラスにバインドしていません。 ES6クラスプロパティ機能を使用して、最もクリーンな方法で問題を回避できます。だからあなたがする必要があるのは:
submit = (e) => {
// some code here
}
矢印関数はそれを自動的にバインドします。コンストラクタでバインドするよりもはるかに優れています。最も重要なことは、決してこのようにしないことです。
onSubmit={() => this.submit()}
これにより、javascriptのオブジェクトである関数が作成され、いくらかのメモリが必要になり、redner関数内に常駐します!それはとても高価になります。 render
関数は何度も実行されるコードの一部であり、submit
関数も作成されるたびに、パフォーマンスに関連する問題が発生します。したがって、コードは次のようになります。
class LoginForm extends Component {
submit = (e) => {
// some code here
}
render() {
return (
<form className="login" onSubmit={ this.submit }>
<button type="submit" className="btn btn-default">Sign in</button>
</form>
);
}
}
export default LoginForm;
ここでは、パフォーマンスの問題は発生せず、バインディングの問題も発生せず、コードの見栄えは格段に良くなります。