7. 延伸開發與相關挑戰


終於到了最後一篇
這篇想以分享經驗的方式跟大家談談 React

我大概從 2016 年開始接觸 React 開發
當時公司從原本的 jQuery 要轉到 React
因為當初有新的工程師導入進來,也沒特別原因,現在想想滿可笑的
後來一路寫到現在,從一開始的 Class Component 到 Pure Component
接下來到了 Functional Component 與 Hook
在樣式的使用上也從純 CSS 到 CSS Module 到現在主流的 Styled Component
基本上能用的都用了,想分享些小小的心得

Button-up v.s. Top-down

在我第一次跟前端切版師合作時
我充分地感受到 React 的思維方式跟傳統的前端很不相同
舉例來說,我們如果想寫一個卡片

傳統寫法:我們會從上到下(Top-down)去思考我們的結構,也就是樣式會從上層往下考慮

<div class="card">
    <div class="title">Title</div>
    <button class="btn">Click me!</button>
</div>
.card {
    .title {
        color: blue;
    }
    .btn {
        color: white;
        background-color: blue;
    }
}

React 寫法:從下往上(Button-up)去構築元件,像堆積木一樣,不用考慮下層

const StyledTitle = styled.div`
    color: blue;
`
const StyledButton = styled.button`
    color: white;
    background-color: blue;
`
const Card = () => {
    return <div>
        <StyledTitle>Title</StyledTitle>
        <StyledButton>Click me!</StyledButton>
    </div>
}

這是在跟別人合作的時候才忽然發現的
雖然說 React 也能寫成 Top-down 的方式
但是我們覺得基本上還是建議從下往上構築
才能夠撰寫出更 Robust 的程式碼

商業驅動設計

不知道有沒有這個名詞
但在開發的過程中,我們嘗試用不同方式來設計我們的專案
我們花了很長的時間不斷重構專案
後來得到的結論是:元件不能驅動設計,商業功能才行

這邊指的設計是程式碼設計,具體來說是軟體設計
正如前幾篇文章所提,component 建議使用功能來區分
我們曾經大量的使用元件種類來區分 component
像是把所有按鈕都放到 components/buttons
把所有卡片都放到 components/cards
把所有輸入框都放到 components/inputs
但是後來的結果是元件完全找不到
因為太常需要依照功能尋找相對應的元件
例如在修付款流程的時候,光是元件就可能有下拉式選單、輸入框、按鈕等等
這樣不管是修正樣式還是程式碼邏輯都會非常可怕

不過其實也是有例外,如果你是專門開發 UI library 的話
像是 bootstrap, ant design, material 等等
他們都是依照元件來切分,畢竟他們就是要提供元件給我們使用
所以如果是自己在使用的話,建議按照商業邏輯的功能進行切分

資料展示分離

這部分原本自己以為已經很了解了
在這次的系列文中又重新體會了如何分離資料處理與樣式展示
在寫 React 的這幾年,從最原本的 All-in-one 元件
像是這樣:

cont Card = () => {
    const handleClick = () => {
        // do lots of things
    }
    return (
        <div class="card">
            <div>Title</title>
            <button class="btn" onClick={handleClick}>Click me!</button>
        </div>
    )
}

後來學習到了 Container & Presenter Pattern
學會將資料層的處理拆分,變成像是這樣:

// container
const Card = () => {
    const handleClick = () => {
        // do lots of things
    }
    return <CardComponent onClick={handleClick} />
}
// presenter
const Card = ({ onClick }) => {
    return (
        <div class="card">
            <button class="btn" onClick={onClick}>Click me!</button>
        </div>
    )
}

不過在撰寫這個系列文的時候
發現 Dan 其實已經提出這個 Pattern 的問題了
雖然這個模式讓資料處理的部分很好的被管理
但是卻會讓樣式分散在 Container 跟 Presenter 兩邊
所以未來會嘗試使用 custom hook 來解決這個問題(可參照上篇的範例)

結語

終於寫完了七天,雖然中間有兩天不小心沒趕出來
但是也算是努力的完成了七篇了(攤
以結論來說好像很難養成寫作的習慣
還需要想想看適合自己的創作方式
未來應該會用工作坊的方式來做這系列的教學
希望這系列對一些人有幫助
下台一鞠躬 <( )>

Typescript 開發 React 的寫法百百種,提供讀者較佳的程式撰寫方式以及專案架構。






Related Posts

DJI Tello 的基礎操作與套件

DJI Tello 的基礎操作與套件

[day08] Closure & Private:番外短篇 隱私成員

[day08] Closure & Private:番外短篇 隱私成員

Day 1:女媧造人,創造你的主人公吧

Day 1:女媧造人,創造你的主人公吧

Nengo AI 入門

Nengo AI 入門

Git & GitHub 心得

Git & GitHub 心得

Vue.js 學習旅程Mile 7 – 資料屬性綁定篇:v-bind

Vue.js 學習旅程Mile 7 – 資料屬性綁定篇:v-bind



Comments