開始一個專案之前,還有一個重要的議題要面對,就是檔案結構(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.
官方文件裡面有提到幾個重要的原則,但也建議我們 Don’t overthink it
:
根據這些原則,考量到我們的Tic Tac Toe裡面不會用到route,然後因為是小遊戲,component也不會有複雜的巢狀結構,所以其實在這個專案我們可以從簡來做就好。
由於我們會用到Redux
,在 redux 和 react 共同構成的架構下,我們將元件分成container
和component
,container資料夾下面我會放Tic Tac Toe的主要元件,這些元件跟這個專案比較有相依性,而component裡面我會放跟這個專案沒有相依性的元件,這些元件只被動的接收資料的傳入,甚至可以單獨抽出來放到別的專案裡被使用,例如我們需要用的圈圈元件,叉叉元件,或是我們自己做的按鈕等等。
下面是我的規劃方式,給大家參考:
之前我是會把containers跟components放在同一層,不過這次因為我們containers下面只會有TicTacToe,所以不會有多個containers下的元件去共用components裡面的元件的狀況,這些components只會被TicTacToe用到,所以我這次就把components放在TicTacToe下面。
Container vs Component
How to better organize your React applications?
如何組織你的 React Redux 的檔案架構
這個專案我會使用到Redux,Redux是為了解決複雜的React App當中,因為裡面有很多層和很複雜的巢狀結構,如果要跨 Component 之間一層一層的傳遞參數,會讓程式碼變得很混亂而不容易維護,所以乾脆有一個中央控管資料的store來儲存所有的state,讓需要用到state參數的component直接跟store拿資料即可。所以就可以避免一些component他明明自己不需要這個state,卻因為它下面的component需要用到這個state,而硬生生把state傳進去又傳出來的狀況。而且如果傳遞中的state,在傳遞過程中,不小心被哪個component無心改動到,就會讓除錯又變得更棘手。
根據上面這些理由,我們的Tic Tac Toe好像也不需要用到Redux,因為我們不會有很多不同的component需要彼此傳遞資料的複雜狀況,反而在簡單的架構下使用Redux會讓專案變得沒有必要的複雜。但是因為是應用練習,為了在將來複雜的專案下我們也能很熟練Redux,所以這邊我們還是來練習使用一下React + Redux的架構。
因為這次的主題是設定在入門之後的應用練習,所以Redux的詳細介紹和安裝方式會直接略過,直接進入到資料結構的規劃,我的安裝設定方式是參考react-boilerplate。我的設定方式或許不是最好的,但是程式碼也會提供給大家做參考。
根據 Day01 列出來的功能,我們要來設計state要儲存的內容以及儲存方式,以下是我設計的參數說明:
blocks = [{id, owner}, {id, owner}, {id, owner}, {id, owner}, ...]
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
資料準備完之後,明天我們就可以根據我們的資料來渲染我們的遊戲頁面啦!