対象は,Reactをこれから勉強しようとしている人.
公式サイトに示されているチュートリアル”三目並べ”を参考に,動作確認する.
公式サイトは少し日本語がおかしく(英語の方がわかりやすい),少々冗長に説明されているため理解に時間がかかった.
この記事では,公式サイトを見るよりもわかりやすく,無駄を省くように心がけて記載している.(あくまで,個人的に)
https://ja.reactjs.org/tutorial/tutorial.html
環境構築に関して
新しい言語やフレームワークを勉強するときに,一番の壁は環境構築である.
この記事の目的は,「Reactを動かしてみる」ことを目的としているため,環境構築を必要としないブラウザ(オンラインエディタ)でコードを書く.
ブラウザでコードを書くことのできるWebサイト(以降オンラインエディタ)は,CodePen,CodeSandboxやStackblitzがある.
記事掲載時の著者のスキル(理解度)
- Web系プログラミング未経験(HTML, JavaScriptすら触ったことがない)
- Fortran, C/C++を科学計算の研究で使用していたため,プログラミングやその設計に関しては理解している.
- Linux関係の知識は十分にあり,サーバやクラスタ構築などを技術を習得済み.
オンラインエディタ
今回はCodeSandboxを使用することにする.
使用方法
以下のURLにアクセスする.
テンプレートが表示される.
Reactチュートリアル
公式サイトに示されているチュートリアル”三目並べ”を参考に,動作確認する.
この記事では,公式サイトを見るよりもわかりやすく,無駄を省くように心がけて記載している.(公式のチュートリアルは長い...)
https://ja.reactjs.org/tutorial/tutorial.html
初期ファイル(スターターコード)の用意
チュートリアルでは,すでに.cssと.jsファイルが予め用意されており,これを基本にReactを学んでいく.
- App.jsを削除する(使用しないため)
- styles.cssを編集する.
- index.jsを編集する.
1. App.jsを削除する(使用しないため)
2. styles.cssを編集する.
すでにテンプレートに記述されているが,以下のように上書き変更する.
body {
font: 14px "Century Gothic", Futura, sans-serif;
margin: 20px;
}
ol, ul {
padding-left: 30px;
}
.board-row:after {
clear: both;
content: "";
display: table;
}
.status {
margin-bottom: 10px;
}
.square {
background: #fff;
border: 1px solid #999;
float: left;
font-size: 24px;
font-weight: bold;
line-height: 34px;
height: 34px;
margin-right: -1px;
margin-top: -1px;
padding: 0;
text-align: center;
width: 34px;
}
.square:focus {
outline: none;
}
.kbd-navigation .square:focus {
background: #ddd;
}
.game {
display: flex;
flex-direction: row;
}
.game-info {
margin-left: 20px;
}
3. index.jsを編集する
すでにテンプレートに記述されているが,以下のように上書き変更する.
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class Square extends React.Component {
render() {
return <button className="square">{/* TODO */}</button>;
}
}
class Board extends React.Component {
renderSquare(i) {
return <Square />;
}
render() {
const status = "Next player: X";
return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
class Game extends React.Component {
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
<div className="game-info">
<div>{/* status */}</div>
<ol>{/* TODO */}</ol>
</div>
</div>
);
}
}
// ========================================
ReactDOM.render(<Game />, document.getElementById("root"));
このような画面が得られるはず.
スターターコードの中身を確認
index.js
は3つのコンポーネントが記述されており,それぞれの役割は次のようである.
- Square(正方形のマス目)
単一の<button>をレンダーする - Board(盤面)
9 個のSquareをレンダーする - Game
後で変更するプレースホルダー値を使ってBoradをレンダーする
データを Props 経由で渡す
ここでは,Board
コンポーネントからSquare
コンポーネントにデータを渡す方法を学ぶ.
Board
のrenderSquare
メソッド内の,value
というprops
をSquere
コンポーネントに渡す.コードを以下のように変更する.
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />;
}
次に,Square
のrender
メソッドで,受け取った値を表示するように,コードを編集する.
class Square extends React.Component {
render() {
return <button className="square">{this.props.value}</button>;
}
}
このような表示が得られる.
インタラクティブなコンポーネントを作成する
インタラクティブなコンポーネントを作成するため,Square
コンポーネントのrender
関数を以下のように変更する.
インタラクティブは対話的という意味で,このコードの場合,「クリックしたとき何かする」ということである.
class Square extends React.Component {
render() {
return (
<button
className="square"
onClick={function () {
alert("click");
}}
>
{this.props.value}
</button>
);
}
}
次に,Square
コンポーネントがクリックされたことを記録し,そのマスに”X”マークを入力するように変更する.まず,コードを以下のように変更する.
- 2-7行目
変数保存のために,this.state.value
を定義.this.stateはクラス内構造体のような印象がある.メンバ変数の方が近いかも. - 11-12行目
クリックされたときにthis.state.value
に”X”を代入する.
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null
};
}
render() {
return (
<button className="square" onClick={() => this.setState({ value: "X" })}>
{this.state.value}
</button>
);
}
}
この段階での,index.js
は以下のようになっている.
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null
};
}
render() {
return (
<button className="square" onClick={() => this.setState({ value: "X" })}>
{this.state.value}
</button>
);
}
}
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />;
}
render() {
const status = "Next player: X";
return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
class Game extends React.Component {
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
<div className="game-info">
<div>{/* status */}</div>
<ol>{/* TODO */}</ol>
</div>
</div>
);
}
}
// ========================================
ReactDOM.render(<Game />, document.getElementById("root"));
三目並べを完成させる
少々記事が長くなってきたので,続きは別ページにまとめることにする.
下記リンクを参照されたい.
最後に
内容に誤りや不具合,ご意見があればコメントを残して頂けるとありがたいです
コメント