Reactを始めようと思ったわけ
EthereumでDAppsを開発するフレームワークにDrizzleというのがあり、このDrizzleがReact/Reduxをラッパーしたフレームワークで作られていたからです。
参考記事:DAppsをReact/Reduxで構築できるDrizzle-Boxを動かしてみる
Reactを正確には把握はしてませんが、スマートコントラクト上の値の変動やイベントに対してReactなら動的に対応できて相性が良さそうなので今後のDApps開発はDrizzleになるのではと密かに思っています。なので基礎のReact/Rduxを学ばないといけないなと思い立ったところです。
けどフロントエンドはBackboneは業務で使ったことがあるけど、Angularは少ししか触ったことないし、最近のフロントエンド事情は全くキャッチアップしていないので何から始めればいいのか全く把握していない状況でした。
そこで色々ら調べた結果react.orgが公式に提供しているチュートリアルが最初は一番いいことがわかったので試してみました。実際すごくよかったのでまずはこれから始めることをオススメします。
ちなみにチュートリアルはReactだけを使うので覚えることは多くないです。
環境と前提知識
- Node.js v8.10.0(nvmで入れると楽)
- Javascriptに関わらずプログラミングを書いたことがあれば簡単に理解できます。
成果物
チュートリアルでは○×ゲームを作ります。仕様は交互にマスを埋めていき1ライン揃えた方の勝ちで勝った方を表示したり、任意の状態に戻したりできます。このシンプルなゲームを作ることでReactの理解を深めようというものです。

ソースコード
ソースコードはわずか150行弱です。1/4くらいはhtmlなので重要な所は少ないです。
Squareがマス、Boardが3×3のマス全体、Gameがターン、勝敗、履歴の管理を行なっています。メインロジックはGameクラス内のhandleClick()で、ここで履歴、ターン、勝敗を管理しています。
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; function Square(props) { return ( <button className="square" onClick={() => props.onClick()}> {props.value} </button> ); } class Board extends React.Component { renderSquare(i) { return ( <Square value={this.props.squares[i]} onClick={() => this.props.onClick(i)} /> ); } render() { return ( <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 { constructor(props) { super(props); this.state = { history: [{ squares: Array(9).fill(null) }], stepNumber: 0, xIsNext: true } } handleClick(i) { const history = this.state.history.slice(0, this.state.stepNumber + 1); const current = history[history.length - 1]; const squares = current.squares.slice(); if (calculateWinner(squares) || squares[i]) { return; } squares[i] = this.state.xIsNext ? 'X' : 'O'; this.setState({ history: history.concat([ { squares: squares } ]), stepNumber: history.length, xIsNext: !this.state.xIsNext }); } jumpTo(step) { this.setState({ stepNumber: step, xIsNext: (step % 2) === 0 }); }; render() { const history = this.state.history; const current = history[this.state.stepNumber]; const winner = calculateWinner(current.squares); const moves = history.map((step, move) => { const desc = move ? 'Go to move #' + move : 'Go to game start'; return ( <li key={move}> <button onClick={() => this.jumpTo(move)}>{desc}</button> </li> ); }); let status; if (winner) { status = 'Winner: ' + winner; } else { status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O'); } return ( <div className="game"> <div className="game-board"> <Board squares={current.squares} onClick={i => this.handleClick(i)} /> </div> <div className="game-info"> <div>{status}</div> <ol>{moves}</ol> </div> </div> ); }; } ReactDOM.render( <Game />, document.getElementById('root') ); function calculateWinner(squares) { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6], ]; for (let i = 0; i < lines.length; i++) { const [a, b, c] = lines[i]; if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { return squares[a]; } } return null; }
まとめ
React.jsはだいぶ理解が進んだのでこのサンプルコードでReduxを使ってReduxの理解も深めてみたいと思います。
上記ソースコードにReduxを導入したものを作成しました。下記是非読んでみてください。
関連記事:Reactだけで作ったアプリにReduxを導入して気づいた利点
髙妻智一
最新記事 by 髙妻智一 (全て見る)
- Polkadot(Substrate)のアドレスとトランザクションについて - 2023-03-09
- 【無料公開】「Goで始めるBitcoin」3章 Bitcoinノードとの通信 技術書典8 - 2020-03-08
- エンジニアがゼロから技術ブログを書くための方法をまとめました - 2019-05-25
コメントを残す