iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0

昨天介紹了在 React 開發的五個思考流程:

  1. 確認 component 不同的呈現狀態
  2. 識別哪些會觸發狀態改變
  3. useState 記憶這些狀態進行操作
  4. 移除多餘的狀態變數
  5. 與事件處理做連結後實際更新狀態

今天會根據這五項做更詳細的介紹。

確認 component 不同的呈現狀態

在開發的時候,會根據 component 可能會發生的情境,會有不同的 UI 呈現。這時候我們就要先把這些畫面用 React 先刻出來。拿官方文件的例子當範例,一個輸入表單可能會有這些狀況,跟 UI 會如何呈現:

  • Empty: 還沒輸入任何東西的時候,提交按鈕(Submit)會無法點擊(disable)
  • Typing: 開始輸入東西後,提交按鈕可以點擊(enable)
  • Submitting: 點擊提交後,送出資料中,讓提交按鈕無法等級並且顯示讀取中(Spinner)
  • Success: 顯示 Thank you 訊息而不是表單
  • Error: 跟 Typing 的時候一樣,但是多了錯誤訊息

當這個階段的時候,我們 component 會根據 status 來顯示不同的 UI,可以透過修改他去看不同顯示方式。也可以直接把所有可能先一次顯示出來,來確認在不同情況下,會不會是我們想要呈現的內容。

識別哪些會觸發狀態改變

會有兩種輸入會觸發狀態的更新:

  • 人工輸入(Human Inputs):使用者手動觸發,像是點擊按鈕,輸入資料,瀏覽連結等。
  • 電腦輸入(Computer Inputs):電腦自動觸發,像是透過網路送出請求後的回傳資料,倒數完成或是圖片讀取等。

透過這些觸發,就可以去更新我們前面提到的狀態,在 React 就是使用 state 紀錄狀態後,透過事件去觸發 UI 更新。以剛剛的範例,就會有以下情況:

  • 更改輸入內容(人工)應該要根據輸入是否是空的,改變狀態成 EmptyTyping
  • 點擊提交按鈕(人工)應該把狀態改成 Submitting
  • 獲得網路回應成功(電腦)應該把狀態改成 Success
  • 獲得網路回應失敗 (電腦) 應該把狀態改成 Error 跟顯示相對應的錯誤訊息

確認好這些流程,我們可以再把流程圖畫出來,就能更好理解我們的狀態改變的流程:
https://ithelp.ithome.com.tw/upload/images/20251007/20163024zeORG0xlRG.png

useState 記憶這些狀態進行操作

在上一個項目有提到在 React 需要用 state 去紀錄狀態,所以我們就需要使用 useState 去定義我們需要用到哪些資料。繼續使用輸入表單的例子,會需要我們輸入的資料,跟錯誤訊息,所以可以寫成:

const [answer, setAnswer] = useState('');
const [error, setError] = useState(null);

接下來我們要檢查 UI 的各種狀態,所以寫成:

const [isEmpty, setIsEmpty] = useState(true);
const [isTyping, setIsTyping] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const [isSuccess, setIsSuccess] = useState(false);
const [isError, setIsError] = useState(false);

但這樣寫會發現,會需要管理很多個 state,變成要寫很多判斷式,所以下一項我們就要來刪除一些比較不重要的 state。

移除多餘的狀態變數

在檢查我們宣告的 state 的時候,官方文件提供三個問題讓我們確認:

  1. 有沒有相抵觸的狀態:像是 isTypingisSubmitting 不可能同時成立,就不會有這個條件下的畫面,等於我們的多了一個用不到的狀態。這在大量使用 boolean 的時候會發生,因為兩個 boolean 就等於會有四個狀況,遇到這種時候,我們可以使用一個 state status 去管理各種情況。
  2. 可不可以透過其他 state 獲得相同資訊:我們可以透過檢查 answer 的長度來確定 isEmpty,就不用特別再多設一個 isEmpty,只需要寫判斷式:answer.length === 0
  3. 能不能透過其他 state 的相反資訊獲得一樣的資訊:跟上個一樣,我們也可以用 error 來確定有沒有錯誤,所以可以用 error !== null 去取代 isError

最後我們整理完的 state 就變成:

const [answer, setAnswer] = useState('');
const [error, setError] = useState(null);
const [status, setStatus] = useState('typing'); // 'typing', 'submitting', or 'success'

直接就從 7 個變成 3 個。

與事件處理做連結後實際更新狀態

確認完 state 架構後,就可以來撰寫各種 handlers 來觸發狀態的更新:

  async function handleSubmit(e) {
    e.preventDefault();
    setStatus('submitting');
    try {
      await submitForm(answer);
      setStatus('success');
    } catch (err) {
      setStatus('typing');
      setError(err);
    }
  }

  function handleTextareaChange(e) {
    setAnswer(e.target.value);
  }

而透過這些 state 的更新,就能順利更改 state 獲得想要的 UI 畫面。

小結

今天算是把昨天講的 component 設計步驟做更詳細的介紹,當然實際的開發的時候的規模不會像這次的範例那麼小,但我們也可以把 component 都切成那麼小,再把他們組起來,所以設計的概念不會隨著規模改變。大家在開發的時候可以多想想自己的 state 怎麼設計。
今天的文章就到這邊告一個段落,感謝大家耐心地看完,如果有任何問題與建議歡迎告訴我,明天見,晚安。


上一篇
Day 22 - 使用 Input Form 介紹 React State 概念
系列文
重溫 React 官方文件回到最初的起點23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言