Reactを初めて触ってみました(tutorialその④)
このページはReact公式ページのtutorialを体験したメモと初心者なりの解釈を記述したページになります。
さて前回は、属性に値を付与してクリックアクションで再描画するところをやっていましたが前回からの続きになります。
ちょっと途中で開発者ツールのことが書いてあったので訳を載せておきます。
開発者ツール
React DevtoolsのChromeとFirefoxの拡張機能を使用すると、ブラウザのdevtoolsのReactコンポーネントツリーを調べることができます。
これにより、ツリー内の任意のコンポーネントの小道具(prop)や状態を調べることができます。
インストールしたら、ページ上の任意の要素を右クリックし、「Inspect」をクリックして開発者ツールを開くと、Reactタブが最後のタブとして表示されます。
私の場合は開発者ツールのconsoleにreactのプラグインツールURLが出ていたのでクリックしてインストールしました。(chromeです)
インストールすると開発者ツールのタブメニュー右側にreactメニューが追加されていました。
ではtutorialの続きに入ります。
リストのステータスに付いて進めていきます
チック・タック・トゥ・ゲーム(このtutorial)のための基本的なビルディング・ブロックがあります。しかし今は、状態は各Squareコンポーネントにカプセル化されています。
完全に機能するゲームを作成するには、1人のプレイヤーがゲームに勝ったかどうかを確認し、XとOを交互に配置する必要があります。
誰かが勝ったかどうかを調べるには、正方形の要素に分割するのではなく、1つの場所に9つの正方形のすべての値を設定する必要があります。
みたいなことが書いてあり続いてWEB翻訳ではちょっと理解できない内容だったのですっ飛ばします。
とりあえず見る限りは順番と誰がクリックしたかボードの状態を保持してクリックでどのマークかをSquareコンポーネントで枠の中を書き換える手順を進めるみたいです。
ここで、正方形がクリックされたときの動作を変更する必要があります。 ボードコンポーネントには、どの四角が塗りつぶされているかが保存されます。つまり、Squareがボードの状態を更新するための方法が必要です。 コンポーネントの状態はプライベートと見なされるため、ボードの状態をSquareから直接更新することはできません。
ちょろっと全体的な概要を書いてありますがまずは正方形がクリックされたときの動作を変更していきます。それにあたってどのマークで枠の中を書き換えるかをやっていきましょうとのこと。
9つの正方形に対応するNULLを持つ配列を作成します
Boardコンポーネント、constructorを追加する
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
};
}
Boardコンポーネント、renderSquareを書き換える
renderSquare(i) {
return <Square value={this.state.squares[i]} />;
}
Squareのvalueにstateの配列squaresの対応場所の値をセットする。
次に四角をクリックしたときに呼び出される関数をBoardからSquareに渡します。
BoardのrenderSquareを再度変更し以下のようにします。
Boardコンポーネント、renderSquareを書き換える
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)}
/>
);
}
翻訳どおりに載せると複数の行に分解して読みやすくして最後にセミコロンを入れましたと書いてあります。
今度はBoardからSquareへの2つの小道具、すなわちvalueとonClickを渡しています。後者はSquareが呼び出すことができる関数です。
Squareに以下の変更を加えましょう。
スクエアのレンダリングでthis.state.valueをthis.props.valueに置き換えます。
スクエアのレンダリングでthis.setState()をthis.props.onClick()に置き換えます。
ステートを持たないので、Squareからコンストラクタ定義を削除してください。
これらの変更の後、Squareコンポーネント全体は次のようになります。
Squareコンポーネント
削除>> constructor(props) {
削除>> super(props);
削除>> this.state = {
削除>> value: null,
削除>> };
削除>> }
Squareコンポーネント
render() {
return (
ここと>> <button className="square" onClick={() => this.props.onClick()}>
ここを>> {this.props.value}
書換え>>
</button>
);
}
これらの変更の後、Squareコンポーネント全体は次のようになります。
class Square extends React.Component {
render() {
return (
<button className="square" onClick={() => this.props.onClick()}>
{this.props.value}
</button>
);
}
}
今四角がクリックされると、ボードによって渡されたonClick関数が呼び出されます。ここで何が起こるかを要約しましょう。
翻訳そのまま
組み込みのDOM <button>コンポーネントのonClick propは、Reactにクリックイベントリスナーの設定を指示します。
ボタンがクリックされると、ReactはSquareのrender()メソッドで定義されたonClickイベントハンドラを呼び出します。
このイベントハンドラはthis.props.onClick()を呼び出します。 Squareの小道具は理事会によって指定された。
BoardはonClick = {()=> this.handleClick(i)}をSquareに渡したので、呼び出されると、ボード上でthis.handleClick(i)が実行されます。
まだBoard上でhandleClick()メソッドを定義していないので、コードがクラッシュします。
DOM <button>要素のonClick属性はReactにとって特別な意味を持っていますが、SquareのonClick propまたはBoardのhandleClickメソッドに異なる名前を付けることができます。しかし、Reactアプリケーションでは、属性の*名前を使用し、ハンドラメソッドの*を扱うのが一般的です。
翻訳だけだと理解できなかったので自分で納得するように理解すると、
Boardコンポーネントのコンストラクタで9つのsquares配列(NULL)がセットされます。そして9つの四角形が作られSquareのvalueの初期値はNULLなので空の四角形、onClickでboardクラスのhandleClick()がレンダリングされたというところでしょうか。
四角をクリックしたときのthis.props.onClick()は、boardでrenderSquareでレンダリングしたときのSquare要素にある onClick={() => this.handleClick(i)になり、propsは要素でそのonClickなのでそういう挙動になるんだなと理解しました。
そうすることによりBoardクラスで値の保持と変更のキャッチでレンダリングをすることができSquareクラスは1つの四角形をレンダリングする機能として動かせるんでしょう。
四角形をクリックしてみてください。handleClickをまだ定義していないので、エラーが発生します。これをBoardクラスに追加します。
Boardコンポーネント
handleClick(i) {
const squares = this.state.squares.slice();
squares[i] = 'X';
this.setState({squares: squares});
}
.slice()を呼び出して、既存の配列を変更する代わりに、四角形の配列をコピーします。
配列データをその構造のまま配列にした感じですね。
今度は、四角形をクリックして再度入力する必要がありますが、状態は各スクエアの代わりにボードコンポーネントに保存されているため、ゲームを続けることができます。
Boardの状態が変わるたびに、Squareコンポーネントは自動的に再レンダリングされます。
対応する四角形
squares[i]にXを代入してセットsetStateしています。
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)}
/>
);
}
Squareはもはや独自の状態を保持しません。それは親ボードからその価値を受け取り、それがクリックされたときにその親に通知する。
我々は、このような制御されたコンポーネントのようなコンポーネントを呼ぶ
|
前回と挙動は変わりませんが履歴を持つ準備ができました! |
ちょっと翻訳メインでわからない部分もあり、そのまま載せてしまっている部分も多いのですが理解できてきました。
コメント
コメントを投稿