やみかわえんじにあ

週7でメンヘラのエンジニア女子が躁うつ闘病生活の日々と大好きな音楽について語るブログです。

【初心者向け】React チュートリアル 応用問題徹底解説1 ~col,rowの表示編~

やみかわえんじにあ、週7でメンヘラしてます。

今回はReactチュートリアル応用問題の解説です。 f:id:mashma_ro:20191118140021p:image 全部で6つあるのですが結構つまずきが多かったので

1問ずつ解説していこうと思います!

-応用問題の内容-

1.履歴内のそれぞれの着手の位置を (col, row) というフォーマットで表示する。

2.着手履歴のリスト中で現在選択されているアイテムをボールドにする。

3.Board でマス目を並べる部分を、ハードコーディングではなく 2 つのループを使用するように書き換える。

4.着手履歴のリストを昇順・降順いずれでも並べかえられるよう、トグルボタンを追加する。 

5.どちらかが勝利した際に、勝利につながった 3 つのマス目をハイライトする。

6.どちらも勝利しなかった場合、結果が引き分けになったというメッセージを表示する。

ja.reactjs.org

この記事では応用問題1の解説をします。

1.履歴内のそれぞれの着手の位置を (col, row) というフォーマットで表示する。

問題の意図は?

OかXの値が入った時に、それがどこに入ったか過去の着手を表示している横に (col,row)というフォーマットで追加して表示しなさいということです。

(col,row)というフォーマット = 盤面上での座標 のことです。

colcolumnの略でcolumnはを表すのでrowを表すのでになります。

つまり、ゲームの盤面は3×3のマスなので縦3グループ横3グループに分けてそれぞれの値を組み合わせたら座標になるということです! その座標history配列に格納すれば履歴に表示できそうですね!

どうやってグループに分けるの?

私も、ロジックの思考回路が弱くてわからなかったので先人の知恵に頼りました。

頼った知恵がこちらです

fukatsu.tech

(これを見て理解できる人はこの先読む必要ないかもしれません)

以下模範解答のコードです。

まずhistory配列のなかに座標を格納したい

f:id:mashma_ro:20191119093627p:plain

これをみたわたしは

なんで座標になるのか分からない!となりました。

1つ1つ見ていきます!

新しく追加したのは、この2つの式です。

1col: 縦を表す式

col: (i % 3) + 1

1row: 横を表す式

row: Math.floor(i / 3) + 1 

iには何が入ってくるのか それが曖昧だったので私はわからないと気づきました。

じゃあ、iって何?

iはBoard classで定義されています。

以下、iの定義がされている箇所です。

f:id:mashma_ro:20191119080021p:plain

ここです!

f:id:mashma_ro:20191119080547p:plain

renderSquareSquareにprps(コンポーネント作成時の値)としてiを渡しています。

返り値として、Squareの値とiは同じと定義しているので

Square(マス目)のvalue(値)がiであることがわかりますね!!

つまり、Bord(盤面)の1つ1つのSquare(マス目)に

値が入る(iがrenderされる)とこうなります。

f:id:mashma_ro:20191119082459p:plain

Square(マス目)はそれぞれ0~8までのを持ってる事がわかりますね。

iが何者なのかわかったので先ほどの式に代入していきましょう。

まず、col: 縦を表す式

col: (i % 3) + 1

Square(マス目)の値(i)3で割った余りに 1を足したものがcolになります!

iを代入するとこうなります。

f:id:mashma_ro:20191119084622p:plain

縦が揃いました!!!!!!!

これにより、colは1~3になりました。 f:id:mashma_ro:20191119085326p:plain

次に、row: 横を表す式

row: Math.floor(i / 3) + 1 

Math.floor() は引数として与えた数以下の最大の整数を返す。Math.floor() - JavaScript | MDN

Math.floorの引数として与えられてるのはiを3で割るという式です。

Square(マス目)の値(i)

3で割った解以下の最大整数に 1を足したものがrowになります!

iを代入するとこうなります。

f:id:mashma_ro:20191119091203p:plain

横も揃いました!!!!!!!

これにより、rowは1~3になりました。

f:id:mashma_ro:20191119091704p:plain

縦と横が揃いました!

f:id:mashma_ro:20191119092148p:plain

なんで座標になるか嫌という程わかったと思うので次に進みます!

この求めた座標を今度は表示しなきゃです。

どこに表示するの?

問題の意図を思い出してください。

OかXの値が入った時に、それがどこに入ったか過去の着手を表示している横に (col,row)というフォーマットで追加して表示しなさいということ。

でしたね!

じゃあ、過去の着手はどこで表示しているのか?

ここです!

f:id:mashma_ro:20191119093107p:plain

ならここをいじれば良さそうですね!

いじれば良さそうだけど、どういじっていいのか思いつかなかったので

またもや先ほどのサイトに頼りました!

以下、頼った知恵です。

f:id:mashma_ro:20191119094225p:plain

以下このコードを見て私が思ったことです。

きっと、step.colで縦の位置step.rowで横の位置持ってきてるんだろうな〜

でも、step.colstep.rowって何してるの…?

step出てくるところ探そう、ありました!

const moves = history.map((step, move) =>

stepは何?

まず、mapオブジェクトから見ていきましょう

配列データ.map( function( value, index, array )

これがmapオブジェクトです。

これが、今回のReact チュートリアルだと何になるのか見ていきましょう。

f:id:mashma_ro:20191119102009p:plain

こうです!

じゃあ、historyってどんな配列なの?

f:id:mashma_ro:20191119102409p:plain

squaresというその時の盤面の状態を表すもの colという置いた列を表すもの rowという置いた行を表すもの この3つの値が入っている配列だとわかります。

stepはhistoryの値なので

step = [ squares,col,row] です!

と言うことは、step.colstep.rowが何してるのかもうわかりましたね?

step.colstepの中からcolの値step.rowstepの中からrowの値持ってくる。

ということです!

最終結果のコード置いておきます!

React - tutorial-1 - CodeSandbox

以上です!

投稿ペースはゆっくりにはなりますが、残り5題も徹底解説します!