はじめに
今回は、State を使った React コンポーネントについて書きたいと思います。
シリーズ
本記事はReact基礎講座のための連載になっています。気になる方のために、前の章は以下です。
これまでの復習、コンポーネントを別ファイルにしてコールする(React基礎講座5) - Qiita
最初の記事は、以下です。
Reactを使ってJSXの内容をレンダリングする(create-react-app)(React基礎講座1) - Qiita
State とは
同じのコンポーネントだけど、コンポーネントが持つ内部の state
の違いによって見た目や振る舞いが変わって行きます。
人間で例える、年齢を state
としてもいいでしょう。また、車で例えると、社名やナンバープレートを state
としてもいいでしょう(それが最適かはわかりませんが)。
React コンポーネント が State を持つと何がいいのか?
コンポーネント中にあるテキストや、cssのクラスなどを動的に変化させることができます。
ES2015(ES6) における クラス構文
React の state
を持った Component は基本、クラス構文と同じような書き方なので、まずは、ES2015(ES6) における クラス構文を学んで理解して行きましょう。
まずは、JSにおける最小限のクラスを書いて行きましょう。
様々な車のオブジェクトを生成する Car
クラスを生成し、インスタンス(オブジェクト)を作ってコンソールで表示させてみましょう。
// jsのクラスの基本的な定義
class Car {
constructor() {}
}
// インスタンス(オブジェクト)の生成
const Prius = new Car();
// コンソールの確認
console.log(Prius);
コンソールは、以下のように表示されます。
引数を受け取れるようにしましょう
Car
クラス に引数として、名前とプレート番号を受け取れるようにします。クラス内では、constructorに定義します。
イオンスタンスを生成する際に、二つの引数を定義します。
実際に書いてみます。
class Car {
constructor(name, number) {
this.name = name;
this.number = number;
}
}
const Prius = new Car("prius", "品川あ00-00");
console.log(Prius);
すると、コンソールではオブジェクトの中に定義された2つの引数に渡した値が表示されています。
クラスなので別のインスタンス(オブジェクト)というか、車(カローラ
)も定義してみましょう。
class Car {
constructor(name, number) {
this.name = name;
this.number = number;
}
}
const Prius = new Car("prius", "品川あ00-00");
console.log(Prius);
const Corolla = new Car("corolla", "品川あ00-00");
console.log(Corolla);
すると、2つ、インスタンス(オブジェクト)ができました。
1つのクラス(テンプレート)から、複数のインスタンス(オブジェクト)ができるところが、クラスの素敵なポイントですね。
では、クラスに関数を持たせてみましょう。(JSでは、クラスが持つ関数をファンクションやメソッドと言います。)
関数の内容は、定義されたデータ(今回なら、名前とプレート番号)を表示する内容にします。では、関数(名前 callMySpec
)を作成し、実際にコールしてみましょう。
class Car {
constructor(name, number) {
this.name = name;
this.number = number;
}
// 関数(名前 `callMySpec`)を作成
callMySpec() {
console.log(this.name, this.number);
}
}
const Prius = new Car("prius", "品川あ00-00");
console.log(Prius);
// 実際にコールしてみました
Prius.callMySpec();
const Corolla = new Car("corolla", "品川あ00-00");
console.log(Corolla);
// 実際にコールしてみました
Corolla.callMySpec();
すると、関数も動いていることがコンソールからわかります。
オブジェクトにドットとつけて、メソッド名()
をつけてクラスメソッドをコールするシンタックスが分かりました。
React における クラスコンポーネント の書き方
ES2015(ES6)におけるクラスシンタックスが分かったので、今度は、ReactのStateを持ったクラスで書くコンポーネントを実装して行きます。
import React from "react";
import { render } from "react-dom";
class Car extends React.Component {
constructor(props) {
super(props);
}
render() {
return <h1>test</h1>
}
}
render(<Car />, document.getElementById("root"));
重要なのは extends React.Component
の部分ですね。
React.Component
の機能を継承(extend
)したCar
クラスである、ということが言えます。
これは、ただのJSのクラスではなく、この後に説明するstate
やprops
(React.Component
の機能)を利用できるCar
クラスと言えます。
そして、constructor内でprops
を受け取ってsuper(props)
で実行する。という記述は定型文として覚えてください。
super
は、extend
した内容を引き継いでいます。書き方(↓)
...
constructor(props) {
super()
}
...
は定型文として覚えてください。
そして、React
における クラスコンポーネントでは、render()
というメソッドが必要になります。これは、どんなコンポーネントを実際に返すかというコンテンツ部分になります。
これらを、まとめて、クラスコンポーネントではなく、 React.Component
で書くと
import React from "react";
import {render} from "react-dom";
class Car extends React.Component {
constructor(props) {
super(props);
}
render() {
return <h1>{this.props.name}</h1>
}
}
render(<Car name='corolla' />,document.getElementById("root"));
これは、nameの内容をprops
として渡しています。
すると、viewにはcorolla
と表示されます。
name
をstate
として定義するには、以下のように
import React from "react";
import { render } from "react-dom";
class Car extends React.Component {
constructor(props) {
super(props);
// stateの定義はオブジェクト記法で定義する
this.state = { name: "corolla" };
}
render() {
return <h1>{this.state.name}</h1>;
}
}
render(<Car />, document.getElementById("root"));
これも同じく、viewにはcorolla
と表示されます。
クリックした時に state(状態) を変更する処理
今度は、クリックした時に <h1>
にある車の車種名のstate(状態) をメーカー名に変更する処理を書いていきます。
具体的の処理の記述は
- 新たに
state
(maker
)とその値(toyota
)を加える -
h1
タグの下にbutton
タグを設置して、クリックした際に発火するメソッドを指定する - メソッドを作成する
- メソッドの内容は「クリックしたら makerのstateの値に変更する」
- その時に
state
を更新するメソッドはsetState
を利用してください - メソッド名は
showMakerName
(this.の影響範囲もあるので、アロー関数で実装する)
- 上に書いたReactの記述から機能を足していきます
記述内容(正解)
import React from "react";
import { render } from "react-dom";
class Car extends React.Component {
constructor(props) {
super(props);
// stateの定義はオブジェクト記法で定義する
// 新たに state ( maker )とその値( toyota )を加える
this.state = { name: "corolla", maker: "toyota" };
}
// h1タグの下に button タグを設置して、クリックした際に発火するメソッドを指定する
render() {
return (
<div>
<h1>{this.state.name}</h1>
<button onClick={this.showMakerName}>add</button>
</div>
);
}
// メソッドを作成する
showMakerName = () => {
this.setState({ name: this.state.maker });
};
}
render(<Car />, document.getElementById("root"));
すると、ボタンタグをクリックしたら、state
(maker
)の値(toyota
)に変更されている事がわかります。
以上です。参考にしてみてください。
参考
- 改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで | 山田 祥寛