先讓我隆重介紹,我們組花了兩週 (感冒也兩週...><) 做出來的真的可以用的 Simple Twitter!
這是 Alpha Camp 畢業前的一個協作專案,著實讓我們在真的進入業界前,先體會了一把在有限時間內,如何團隊協作開發一個完整的作品。
這次我們的小組採兩前端、兩後端的前後分離開發模式,要做到的指定功能有:
在真正開發前我們需要訂下:
我們在開發期間,每天早上 9:00 也都會在 Discord 開晨會來追蹤大家前一天的任務完成進度並提出今日自己的預計完成進度,這個時間就是用來動態調節 task list 並且討論一些問題用的。
而在前端分工部分,因為是用 React 開發,我們一開始也初步擬出可能會用到的 component,並按照網頁的相似性切分出各自需要負責的部分,比如我的前端夥伴 Mika 負責需要用到 <AuthInput/> 元件部分的切版,比如登入 / 註冊頁,而我負責主頁與個別推文的渲染。
在開發前期,前端的工作就是想辦法做出畫面來,不得不說,真的是把這半年來學的所有切版技巧都用上了,position
啦、flex
啦、文字縮排的 overflow: hidden, white-space: nowrap, text-overflow: ellipsis
,著實練了一番切版技巧,順帶著連 SCSS 的寫法都提升了 (styled-components 可以用 SCSS 的寫法真的很方便)。
通常切版上的問題並不會花去我們太多時間,那時我們解最久的反而是 pull request 衝突,猶記得,那個晚上,我們解了快一個小時的衝突 XD。而衝突的可能性真的有很多,其中就包括我們兩個人都跑去動了路由 www
我自己花最多時間處理的問題是在串接 API 後要實作互動功能時 (我們採部分頁面切完就先串 API 的模式)。先感恩一下我們的後端夥伴,整理了一份詳細的 Notion 清單讓我們前端可以清楚知道會獲得的資料格式與要回傳的內容。那為什麼問題會是發生在串 API 之後呢?原因在於獲得 API 回傳資料後的管理。
在這裡舉個例子,如下圖,有一個推薦跟隨欄,我要它按下跟隨或取消跟隨後按紐的樣式能改變,嗯,這個前端不用打 API 就做得到了,加了 API 也 easy 嘛 ~ 讓按鈕樣式隨著資料裡的 isFollowed 內容作渲染就可以了啊。那麼,如果讓它能和它人資訊頁的按鈕作連動呢?
我一開始的想法是:在推薦跟隨的 component 中的 useEffect 的依賴綁成 API 請求回來的資料,目的是想一但資料改變就重新渲染推薦跟隨畫面。實際上,的確是讓兩邊連動了,但這時後端回饋「前端有無限重複請求的狀況喔!」,燈愣!這還只是個小專案,若是大專案可能就等著讓網頁效能卡到死吧...
這真的是一個棘手的狀況,後來決定改成把 API 請求回來的推薦跟隨資料先儲存在 state 內,並透過 context 讓這個 state 可以在其他元件中使用。我們決定讓畫面的渲染改成依照 state 的更新去做重新渲染,具體如下:
Ok,這樣我們做到了在他人資訊頁點擊按鈕會讓右方的按鈕也一起變換,但現在只能單方面變換,所以我們必須在推薦跟隨那裏也按照上面的模式,在按下按鈕後打一次獲得用戶資訊的 API,並把新資料存進 state 中,然後透過 context 遞給他人資訊頁重新渲染。
一切似乎合情合理!透過這樣的方式的確讓兩邊可同步按鈕樣式,也解決了重複請求問題。
但是!對,就是這個但是,又是資料管理的問題,我們一開始設置管理用戶資料的 state 時只設了一個 userData,他必須按照今天動態路由所獲得的用戶 id 來更新內部的資料,也就是他既要儲存現正使用者的資料,也要能儲存其他用戶的資料。
一開始這種想法似乎沒什麼問題,因為一換頁就重打一次 API 取得用戶資料更新 state 裡面內容好像不會出什麼差錯。但問題就發生在推薦跟隨欄為了讓按鈕按下去後能讓他人資訊頁面的按鈕樣式也同步轉換,因此裡面會打一次獲得用戶資料的 API。
當你在主頁瀏覽推文時,去點了右方推薦跟隨欄的按鈕,燈愣,因為打了一次取得用戶資料的 API,而這時請求的 id 會是你剛剛按下要跟隨的那個用戶,然後因為 userData 被更新,直接主頁,乃至設定頁,你的頭像、名稱、帳號...種種資訊都變成對方的了 www
於是我們從一個資料管理的問題又到了另一個資料管理的問題:資料汙染。
其實原因也很簡單,就是前面提到的,現正使用者和其他用戶的資料存在同一個狀態中,所以解方也很簡單,就是拆出兩個 state。比方說我們後來拆出 userData 和 otherUserData,前者專門管理現正使用者資料,後者專門管理其他用戶的資料,而拆開之後,我們發現,連渲染也變順了 XD
這整個就是一個問題的 combo:
總而言之,類似這種資料管理的問題往往都是處理最久的,但也給了我一個很好的經驗就是以後專案開始時一定要先好好擬定資料流...。相較之下,跑版問題反而解起來輕鬆一些。
雖然這次沒做到挑戰功能有點小可惜,但回顧整個專案真的是進步良多,無論是 React 的應用、切版的功力還是 API 串接等功力都有大幅度提升。與夥伴們一起討論、demo、debug 的經驗更是難得。
因為很多東西都是邊做邊學,比方說巢狀路由、GitHub pull request,專案一開始也是搞得有些頭疼。但是網路多方的資源以及與夥伴一同嘗試真的是能渡過許多難關的法門之一。
最後要感謝團隊的夥伴 Mika、芋頭、Winston。良好的團隊溝通與分工是我們能順利結案的重要原因。在後端忙碌完 API 的開發後,芋頭與 Winston 總是能主動承擔跟 AC 溝通、會議紀錄以及 Demo 的工作,讓前端的我們能更專注於開發。與 Mika 的討論中,也總是能獲得新的思路,許多解方常常是這樣討論的過程中出現的。也要謝謝 Mika 當初的邀請,才讓我有幸遇到這麼優秀的夥伴們!祝福你們,也祝福我自己,轉職順利!畢業快樂!