iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 3
0
Modern Web

以經典小遊戲為主題之ReactJS應用練習系列 第 3

Day03 - Tic Tac Toe篇:檔案結構與資料結構規劃

檔案結構規劃

開始一個專案之前,還有一個重要的議題要面對,就是檔案結構(File Structure)的規劃,當專案的檔案及頁面越來越多,功能越來越複雜,好的檔案結構規劃可以幫助我們在複雜及眾多的檔案當中輕鬆且快速的找到我們想要的目標程式碼,也可以幫助我們減少犯錯的機會。

但身為一個ReactJS的入門開發者,在這部分通常會相對沒有經驗,可以想到的部分沒有辦法很縝密,所以我上網做了一點功課,並且挑了幾篇我自己覺得不錯的來跟大家分享。

在React的官方文件裡有針對這個問題來做回答:

Is there a recommended way to structure React projects?
React doesn’t have opinions on how you put files into folders. That said there are a few common approaches popular in the ecosystem you may want to consider.

React的官方文件: File Structure

官方文件裡面有提到幾個重要的原則,但也建議我們 Don’t overthink it:

  1. Grouping by features or routes
  2. Grouping by file type
  3. Avoid too much nesting
  4. Don’t overthink it

根據這些原則,考量到我們的Tic Tac Toe裡面不會用到route,然後因為是小遊戲,component也不會有複雜的巢狀結構,所以其實在這個專案我們可以從簡來做就好。

由於我們會用到Redux,在 redux 和 react 共同構成的架構下,我們將元件分成containercomponent,container資料夾下面我會放Tic Tac Toe的主要元件,這些元件跟這個專案比較有相依性,而component裡面我會放跟這個專案沒有相依性的元件,這些元件只被動的接收資料的傳入,甚至可以單獨抽出來放到別的專案裡被使用,例如我們需要用的圈圈元件,叉叉元件,或是我們自己做的按鈕等等。

下面是我的規劃方式,給大家參考:
file-structure

之前我是會把containers跟components放在同一層,不過這次因為我們containers下面只會有TicTacToe,所以不會有多個containers下的元件去共用components裡面的元件的狀況,這些components只會被TicTacToe用到,所以我這次就把components放在TicTacToe下面。

Container vs Component
How to better organize your React applications?
如何組織你的 React Redux 的檔案架構

Tic Tac Toe資料儲存規劃

選用React + Redux架構

這個專案我會使用到Redux,Redux是為了解決複雜的React App當中,因為裡面有很多層和很複雜的巢狀結構,如果要跨 Component 之間一層一層的傳遞參數,會讓程式碼變得很混亂而不容易維護,所以乾脆有一個中央控管資料的store來儲存所有的state,讓需要用到state參數的component直接跟store拿資料即可。所以就可以避免一些component他明明自己不需要這個state,卻因為它下面的component需要用到這個state,而硬生生把state傳進去又傳出來的狀況。而且如果傳遞中的state,在傳遞過程中,不小心被哪個component無心改動到,就會讓除錯又變得更棘手。

redux-flow
react-redux-framework

根據上面這些理由,我們的Tic Tac Toe好像也不需要用到Redux,因為我們不會有很多不同的component需要彼此傳遞資料的複雜狀況,反而在簡單的架構下使用Redux會讓專案變得沒有必要的複雜。但是因為是應用練習,為了在將來複雜的專案下我們也能很熟練Redux,所以這邊我們還是來練習使用一下React + Redux的架構。

因為這次的主題是設定在入門之後的應用練習,所以Redux的詳細介紹和安裝方式會直接略過,直接進入到資料結構的規劃,我的安裝設定方式是參考react-boilerplate。我的設定方式或許不是最好的,但是程式碼也會提供給大家做參考。

tic-tac-toe/src/store/

資料儲存規劃

根據 Day01 列出來的功能,我們要來設計state要儲存的內容以及儲存方式,以下是我設計的參數說明:

  1. gameScale:
    • 因為我們要做的是一個棋盤大小可以伸縮自如的圈圈叉叉遊戲,所以我們需要有一個參數來存目前棋盤大小,當調整棋盤大小的時候,只要改變這個參數就可以了,這裡我命名為gameScale。例如,當棋盤為3x3的時候,gameScale為3,當棋盤為5x5的時候,gameScale為5。
  2. winnerCondition:
    • 除了伸縮自如的棋盤之外,我們的勝利條件也可以讓玩家自行調整,可以3子連成一直線為獲勝,或是調整成5子連成一直線為獲勝,所以在winnerCondition儲存這個數字,當條件改變的時候,就調整這個參數。
  3. blocks:
    • 這邊我用一個物件的陣列來儲存棋盤上每一個格子當下的狀態,每一個物件有一個id及owner,id用來幫助我在運算的時候找到我想要的那個指定的格子,owner用來儲存目前這個格子標示的是圈圈,還是叉叉,還是空的。
    blocks = [{id, owner}, {id, owner}, {id, owner}, {id, owner}, ...]
    
  4. currentRole:
    • 顧名思義就是當前是輪到誰要下棋,是圈圈還是叉叉。下面是我在constants.js裡面存的參數資料,我用1代表圈圈,用-1代表叉叉,因為我希望乘以-1就可以達到換人的效果。然後下面PLAYER_1意思是遊戲開始的時候先攻的人,我這邊讓圈圈可以先攻。
    export const CIRCLE = 1;
    export const CROSS = -1;
    export const TOGGLE = -1;
    export const PLAYER_1 = CIRCLE;
    
    export const GAME_WRAPPER_SIZE = 600;
    export const DEFAULT_GAME_SCALE = 3;
    export const DEFAULT_WINNER_CONDITION = 3;
    
    tic-tac-toe/src/containers/TicTacToe/constants.js
  5. isSinglePlayer
    • Day01 的時候我們有說我們希望可以切換讓自己跟電腦對戰的模式,或是跟朋友一起玩的模式,所以isSinglePlayer為true的時候,會讓電腦成為你的對手。

data-structure

資料準備完之後,明天我們就可以根據我們的資料來渲染我們的遊戲頁面啦!


上一篇
Day02 - Tic Tac Toe篇:開發環境準備
下一篇
Day04 - Tic Tac Toe篇:頁面佈局規劃及棋盤實現
系列文
以經典小遊戲為主題之ReactJS應用練習30

尚未有邦友留言

立即登入留言