はじめに
今回は、前回学んだState
を使ったReact
コンポーネントを利用して、ちょっとしたアプリケーションを作りたいと思います。
シリーズ
本記事はReact基礎講座のための連載になっています。気になる方のために、前の章は以下です。
State を使った React コンポーネント(React基礎講座6) - Qiita
最初の記事は、以下です。
Reactを使ってJSXの内容をレンダリングする(create-react-app)(React基礎講座1) - Qiita
テストの出来栄えを判定するちょっとしたアプリケーション
今回作成する、ちょっとしたアプリケーションの内容を説明します。
例えば、学校の100満点のテストを受けた時に
- 100だった場合
- 80点以上だった場合
- 50点以上だった場合
- それ以下だった場合
に、viewが変わるような仕掛けを、State を使った React コンポーネントを利用して作成していきましょう。
Reactアプリを作成する際の採用構成ファイル
import React from "react";
import { render } from "react-dom";
render(<App />, document.getElementById("root"));
次に、React.Componentを作成していきましょう。
主に必要な記述は
- extends
- constructor
- render
でしたね。では、クラス名はテストなので、exam
として書いていきましょう。
今回はテストの点数をstateにしてください。名前はscore
(初期値: 10)とでもしていきましょう。
すると、こんな感じにかけると思います。
import React from "react";
import { render } from "react-dom";
class Exam extends React.Component {
constructor(props) {
super(props);
this.state = { score: 10 };
}
render() {
return <h1>{this.state.score}</h1>;
}
}
render(<Exam />, document.getElementById("root"));
viewには10
とだけ、表示されたと思います。
では、次に、温度変化をコントロールするボタンを作っていきます。
主な手順は
-
+
ボタンと-
ボタンのjsxを作成してください - 上記のボタンから、stateを変更するようなメソッドをアロー関数で作成してください
- メソッド名
- 1+する方は
onPlusBtnClick()
- 1-する方は
onMinusBtnClick()
- 1+する方は
- メソッド名
以下が、正解(書き方はいくらでもありますが...)。
import React from "react";
import { render } from "react-dom";
class Exam extends React.Component {
constructor(props) {
super(props);
this.state = { score: 10 };
}
render() {
return (
<div>
<h1>{this.state.score}</h1>
<button onClick={this.onPlusBtnClick}>+</button>
<button onClick={this.onMinusBtnClick}>-</button>
</div>
);
}
onPlusBtnClick = () => {
this.setState({ score: this.state.score + 1 });
};
onMinusBtnClick = () => {
this.setState({ score: this.state.score - 1 });
};
}
render(<Exam />, document.getElementById("root"));
こんな感じですね。
同じような要領で、+10、そして、-10になるようなJSXとメソッドも作って見ましょう。
以下が、正解(書き方はいくらでもありますが...)。
import React from "react";
import { render } from "react-dom";
class Exam extends React.Component {
constructor(props) {
super(props);
this.state = { score: 10 };
}
render() {
return (
<div>
<h1>{this.state.score}点</h1>
<button onClick={this.onPlusBtnClick}>+</button>
<button onClick={this.onMinusBtnClick}>-</button>
<button onClick={this.onPlusBtnTenClick}>+10</button>
<button onClick={this.onMinusBtnTenClick}>-10</button>
</div>
);
}
onPlusBtnClick = () => {
this.setState({ score: this.state.score + 1 });
};
onMinusBtnClick = () => {
this.setState({ score: this.state.score - 1 });
};
onPlusBtnTenClick = () => {
this.setState({ score: this.state.score + 10 });
};
onMinusBtnTenClick = () => {
this.setState({ score: this.state.score - 10 });
};
}
render(<Exam />, document.getElementById("root"));
こんな感じですね。
テストの出来栄えを判定する条件を追加する
学校の100満点のテストを受けた時に
- 100だった場合: 天才
- 80点以上だった場合: 秀才
- それ以下だった場合: 伸び代あり!
という評価を点数に合わせて動的に表示が変わるように作成しましょう。
手順としては
- 上の条件で文字列を返すようなメソッドをアロー関数で作成する
- メソッド名は
evaluationScore
- メソッド名は
- そのメソッドを受け取るJSXを
h1
以下に用意する
以下が、正解(書き方はいくらでもありますが...)。
import React from "react";
import { render } from "react-dom";
class Exam extends React.Component {
constructor(props) {
super(props);
this.state = { score: 10 };
}
render() {
return (
<div>
<h1>{this.state.score}点</h1>
<p>評価:{this.evaluationScore(this.state.score)}</p>
<button onClick={this.onPlusBtnClick}>+</button>
<button onClick={this.onMinusBtnClick}>-</button>
<button onClick={this.onPlusBtnTenClick}>+10</button>
<button onClick={this.onMinusBtnTenClick}>-10</button>
</div>
);
}
onPlusBtnClick = () => {
this.setState({ score: this.state.score + 1 });
};
onMinusBtnClick = () => {
this.setState({ score: this.state.score - 1 });
};
onPlusBtnTenClick = () => {
this.setState({ score: this.state.score + 10 });
};
onMinusBtnTenClick = () => {
this.setState({ score: this.state.score - 10 });
};
evaluationScore = score => {
if (score >= 100) {
return "天才";
} else if (score >= 80) {
return "秀才";
} else {
return "伸び代あり!";
}
};
}
render(<Exam />, document.getElementById("root"));
こんな感じですね。
テストの出来栄えを判定してCSSのスタイリングも変化するように条件を追加する
今度は、state
(テストの点数)の値に伴ってCSSが変化するような変更を加えていきましょう。
手順としては以下のような感じ
-
h1
タグにclassName
(Reactでスタイリングする場合の書き方)を指定して、関数evaluationScore
に引数this.state.score
を渡して、そこから帰る文字列をクラス名として利用する -
style.css
にスタイルを書いて、index.js
でそれをimport
する - cssと
index.js
は同じ階層 - 関数(
evaluationScore
)が返す文字列も日本語から英語にします
import React from "react";
import { render } from "react-dom";
import "./style.css";
class Exam extends React.Component {
constructor(props) {
super(props);
this.state = { score: 10 };
}
render() {
return (
<div>
<h1 className={this.evaluationScore(this.state.score)}>
{this.state.score}点
</h1>
<p>評価:{this.evaluationScore(this.state.score)}</p>
<button onClick={this.onPlusBtnClick}>+</button>
<button onClick={this.onMinusBtnClick}>-</button>
<button onClick={this.onPlusBtnTenClick}>+10</button>
<button onClick={this.onMinusBtnTenClick}>-10</button>
</div>
);
}
onPlusBtnClick = () => {
this.setState({ score: this.state.score + 1 });
};
onMinusBtnClick = () => {
this.setState({ score: this.state.score - 1 });
};
onPlusBtnTenClick = () => {
this.setState({ score: this.state.score + 10 });
};
onMinusBtnTenClick = () => {
this.setState({ score: this.state.score - 10 });
};
evaluationScore = score => {
if (score >= 100) {
return "genius";
} else if (score >= 80) {
return "excellence";
} else {
return "potential";
}
};
}
render(<Exam />, document.getElementById("root"));
/* 青 */
.genius {
color: #2f00ff;
}
/* 緑 */
.excellence {
color: #00ff0d;
}
/* 赤 */
.potential {
color: #ff0000;
}
こんな感じですね。
リファクタ
多少、冗長な書き方があるので、短く書いていきましょう。
{}
で必要なものを取り出します。
例えば、この記述 this.state.score
const { score } = this.state
これは、state
の中に、score
があれば、constで定義したscore
に入れる。という意味です。こうかけば、いちいち this.state.score
書かなくても、score
だけで済みます。
renderメソッドの中と、その下のsetState
する関数の中で const { score } = this.state;
を書いています。
import React from "react";
import { render } from "react-dom";
import "./style.css";
class Exam extends React.Component {
constructor(props) {
super(props);
this.state = { score: 10 };
}
render() {
const { score } = this.state;
return (
<div>
<h1 className={this.evaluationScore(score)}>
{score}点
</h1>
<p>評価:{this.evaluationScore(score)}</p>
<button onClick={this.onPlusBtnClick}>+</button>
<button onClick={this.onMinusBtnClick}>-</button>
<button onClick={this.onPlusBtnTenClick}>+10</button>
<button onClick={this.onMinusBtnTenClick}>-10</button>
</div>
);
}
onPlusBtnClick = () => {
const { score } = this.state;
this.setState({ score: score + 1 });
};
onMinusBtnClick = () => {
const { score } = this.state;
this.setState({ score: score - 1 });
};
onPlusBtnTenClick = () => {
const { score } = this.state;
this.setState({ score: score + 10 });
};
onMinusBtnTenClick = () => {
const { score } = this.state;
this.setState({ score: score - 10 });
};
evaluationScore = score => {
if (score >= 100) {
return "genius";
} else if (score >= 80) {
return "excellence";
} else {
return "potential";
}
};
}
render(<Exam />, document.getElementById("root"));
これで、冗長な書き方が多少なくなったかと思います。
以上です。参考にしてみてください。
参考
- 改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで | 山田 祥寛