iT邦幫忙

2021 iThome 鐵人賽

DAY 23
0
自我挑戰組

30天CSS、JS、React打造專案零組件系列 第 23

DAY23 - [React hook] useState

  • 分享至 

  • xImage
  •  

今日文章目錄

  • 前言
  • 需求說明
  • 過程紀錄
  • 參考文章

名詞解釋真的好難,會寫教學文還讓大家看得懂的前輩真的好厲害~


前言

延伸 昨天提到的 Brower DOM ≠ React DOM,那麼兩者之間的差異性?

  • Brower DOM:
    瀏覽器將HTML檔解析成DOM tree,加入CSS樣式與JS,渲染成我們看到的網頁。每當DOM節點有任何更新,都要重新渲然整個新的DOM,這樣會影響效能,造成使用者體驗不佳。

    想想看,如果我們打開Facebook,隨時都會收到即時貼文與訊息,如果每一個更新都要re-render DOM,那還得了?

  • React DOM:
    Facebook 建立的React DOM,當React DOM節點有任何更新,一樣會重新繪製React DOM,但不一樣的是:
    React DOM會比較前後是哪個節點有更新,針對有更新的部分作 re-render,並使用ReactDOM.render()確保 Brower DOM 與 React DOM資料一致。解決重複渲染導致的效能問題。

React Virtual DOM圖片來源參考文章: React Virtual DOM Explained in Simple English

剛剛提到 React DOM 節點更新,其實就是 state 的變化。(但為了維護更好的效能,並不是一有state更新,就馬上跑去告訴Brower DOM。而是累積一部分新的state,再一次去統一更新Brower DOM的資料。所以你之後可能會發現,有些時候更新 state,畫面並沒有同步更新。)

React 提供 useState方法,讓我們可以輕易操控資料變化。我們可以呼叫useState,並透過陣列解構方式自訂state名稱:

    const [ 自訂state名稱, 自訂更新state方法的名稱] = useState(state初始值);
    const [ state, setState ] = useState("");
  • state初始值: 畫面第一次 render的state預設值。
  • 自訂更新state方法的名稱: 一律以setXXX開頭。

還有,React 用 function component 回傳 React element,而我們也得以在element操作一些變數。
記得,component命名開頭都是大寫,用來與 HTML標籤 做區別。

天哪,終於要來實作了


需求說明

  • 輸入代辦項目,點擊送出,顯示清單。
  • 一個輸入框、一個提交按鈕、ul清單。

過程紀錄

  • 建立一個 component:
export default function ToDoList() {
    // do something
    
    return(        // element
         <>
          <Space>
            <Input
              value={inputValue}
              onChange={(e) => setInputValue(e.target.value)}
            />
            <Button type="primary" onClick={handleSubmit}>+</Button>
          </Space>
          <ul>
            {toDoData.map((item) => (
              <li id={item.id}>{item.value}</li>
            ))}
          </ul>
        </>
    )
}
  • 綁定 input value 與 清單資料:
    const [ inputValue, setInputValue ] = useState("");
    const [toDoData, setToDoData] = useState([]);
  • 我使用 Antd 的 UI 與方法,點擊送出按鈕,執行 setInputValuesetToDoData 更新值。
  const handleSubmit = () => {
    if (inputValue) {
      const newValue = {
        id: Date.now(),
        value: inputValue,
        status: UNFINISHED,
        spendTime: 0,
      };
      setToDoData([...toDoData, newValue]);
      setInputValue('');
    } else {
      AlertNotification({
        type: 'warning',
        message: '請先輸入代辦事項!',
      });
    }
  };
  • 顯示效果:
    顯示效果

參考文章


上一篇
DAY22 - [React] 資料夾結構概述
下一篇
DAY24 - [React hook] component 零組件
系列文
30天CSS、JS、React打造專案零組件30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言