回到部落格

2024-02-23

【React作品集】Todo List專案 part.3

【React作品集】Todo List專案 part.3

原文發表於 Medium

在這個階段,我們要讓前端的資料狀態可以被儲存起來。若您是第一次到這來,請先至:【React作品集】Todo List專案 part.1

由於涉及到後端API的部分篇幅太大了,因此我先以用戶端的localStorage 來操作。

創建localStorage 資料

首先我們先做出儲存到localStorage 的機制,以下將之前的useEffect改寫一下,並加入一個新的useState到App.tsx裡面:

//新的userID state,加入到App function中。  
  const [userID, setUserID] = useState<string>("");  
  
useEffect(() => {    
    //若localStorage中沒有一筆資料Key值是"MyTodoListData"的話就建立一個新的初始狀態。  
    if (!localStorage.getItem("MyTodoListData")) {  
  
      //自建的新初始狀態  
      const initTodoList: TodoItemsList = {  
        userID: uuid(), //由於資料結構中有userID,我們使用uuid產出ID。  
        todoList: [],  
      };  
  
       //把資料set到localStorage裡面,這邊要記得把資料JSON化!  
      localStorage.setItem("MyTodoListData", JSON.stringify(initTodoList));  
      setTodos(initTodoList.todoList);  
      setUserID(initTodoList.userID);  
    }   
  //若localStorage中有資料的話,就會跑下面的流程  
  else {  
      //抓取localStorage資料分別放到todos跟userID兩個state中  
      const saveData = JSON.parse(localStorage.getItem("MyTodoListData")!);  
      setTodos(saveData.todoList);  
      setUserID(saveData.userID);  
    }  
  }, []);  
     //相依陣列是空的,代表只在載入頁面時執行一次。  
      //這種開啟時更新狀態的方式,又叫作初始化。  
  
  
```  
說明:  
  
上面有三個地方要注意:  
  
1.有多新增一個userID的useState。  
  
2. 安裝uuid,  
可以參照https://www.npmjs.com/package/uuid 安裝與import。  
  
3. JSON.stringfy()跟JSON.parse()不要忘記了,不然會有問題。  
  
若您從來沒有接觸過JSON,推薦您參看https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/Objects/JSON  
以及  
*JSON.stringfy():  
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify  
*JSON.parse():  
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse  
  
```

你是不是以為好了?才沒,不信的話就重新整理看看!

有沒有發現Todo項目都沒了?

檢查storage,頁面上按下f12打開「開發人員工具」,然後點選「應用程式」tab:

發現我們在useEffect 裡面加入的資料在呀,可是為什麼是空的array?因為我們在storage裡面資料從創始之後都沒有更新,一直保留在初始狀態。

隨著頁面state更新localStorage

那要怎麼讓頁面state更新時,同時更新localStorage?我們需要多加一個專門處理這項功能的useEffect !

  //直接寫在原本的useEffect下方即可。  
  useEffect(() => {  
  
    //確認資料在初始化useEffect中確實創立或抓到userID之後,才開始把state抓入更新  
    if (userID) {  
      const newTodoList: TodoItemsList = {  
        userID: userID,  
        todoList: todos,  
      };  
      localStorage.setItem("MyTodoListData", JSON.stringify(newTodoList));  
    }  
  
  }, [todos]);  
      //相依陣列中加入todos,讓使用者改變todos狀態時就更新localStorage

搞定!現在你就擁有一個專屬自己的Todo List了!

useEffect可以有很多個,分別讓他們在不同的時間作動,可以造就整齊有秩序的資料流與相應的副作用。

到現在為止,有關Todo List的專案開發已經初步完成。

但是還有美中不足的一點,就是Todo項目的文字不能修改:如果我原本要打籃球,但下雨了要改成在室內打桌球,就需要刪掉打籃球的項目,然後新增打桌球的項目,有點麻煩。

為了要改善這一點,在下一篇中,我們就來加入修改項目內容的功能。

若喜歡這樣的文章,還請給我幾個掌聲,您的支持是我寫下去的原動力!