iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
自我挑戰組

新手前端與真實世界的開發 feat.React 與他的夥伴系列 第 25

Day-25 專案演練 - 創造全局待辦清單 redux

  • 分享至 

  • xImage
  •  

Day-25 專案演練 - 創造全局待辦清單 redux

今天想來做一件事情,把 list 變成全局 state,接下來讓 HomPage 也能取得這份資料,並且顯示一筆在快速區域,接下來把新增待辦的功能也使用 redux 來管理,這樣能讓我們在 HomePage 也能拿到 list。

撰寫 todoSlice

rudex 本身為人詬病的一個缺點是太多的模板代碼,我感覺這可以是一個缺點,也可以是一種優點,優點就是像一樣規格的程式碼重複做就能夠用統一的方式來管理功能,因為是 todo 的功能所以叫做 todoSlice,新增 todoSlice 資料夾,並且增加 todoSlice.ts 與 index.d.ts :

todoSlice.ts

import { createSlice } from "@reduxjs/toolkit";
import type { PayloadAction } from "@reduxjs/toolkit";
import { TodoState, RootState } from "./index.d";

const initialState: TodoState = {
  list: [],
};

const todoSlice = createSlice({
  name: "todo",
  initialState,
  reducers: {
    // 之後要放相關功能
  },
});

// export const {  } = todoSlice.actions;
export const selectList = (state: RootState) => state.todoSlice.list;
export default todoSlice.reducer;

記得加一下 index.d.t :

index.d.ts

import { store } from "../store";

export type TodoState = {
  list: array;
};

export type RootState = ReturnType<typeof store.getState>;

最後,在 store 掛進去 :

import { configureStore } from "@reduxjs/toolkit";
import modalSlice from "./modalSlice/modalSlice";
import todoSlice from "./todoSlice/todoSlice"; // 引入一下

export const store = configureStore({
  reducer: {
    modalSlice,
    todoSlice, // 放這邊
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

新增 list

首先,從 todoPage 中把資料放到 todoSlice 中 :

...

const initialState: TodoState = {
  // 從這裡開始
  list: [
    {
      id: "0",
      time: "2018-07-22",
      title: "購物",
      info: "日用品",
      checked: false,
    },
    {
      id: "1",
      time: "2022-09-15",
      title: "鐵人賽",
      info: "day-10",
      checked: true,
    },
    {
      id: "2",
      time: "2022-09-25",
      title: "摺棉被",
      info: "早上就是要摺棉被",
      checked: false,
    },
  ],
};

...

製作 todo 相關功能

先做一個新增待辦事項當作代表 :

    addTodo: (state: TodoState, action: PayloadAction<[]>) => {
      state.list = [...state.list, action.payload];
    },

最後 todoSlice 的呈現 :

import { createSlice } from "@reduxjs/toolkit";
import type { PayloadAction } from "@reduxjs/toolkit";
import { TodoState, RootState } from "./index.d";

const initialState: TodoState = {
  list: [
    {
      id: "0",
      time: "2018-07-22",
      title: "購物",
      info: "日用品",
      checked: false,
    },
    {
      id: "1",
      time: "2022-09-15",
      title: "鐵人賽",
      info: "day-10",
      checked: true,
    },
    {
      id: "2",
      time: "2022-09-25",
      title: "摺棉被",
      info: "早上就是要摺棉被",
      checked: false,
    },
  ],
};

const todoSlice = createSlice({
  name: "todo",
  initialState,
  reducers: {
    addTodo: (state: TodoState, action: PayloadAction<[]>) => {
      state.list = [...state.list, action.payload];
    },
  },
});

export const { addTodo } = todoSlice.actions;
export const selectList = (state: RootState) => state.todoSlice.list;
export default todoSlice.reducer;

重新再 todoPage 取得 list

接下來回到 todoPage 用 Selector 取得 list,取代掉 todoPage 原本有的 list state :

// const [isOpen, setIsOpen] = useState(false);
const list = useAppSelector(selectList);

repo

附上程式碼

結語

今天完成了將 list 用 redux 轉為全局狀態,這樣我們在每個元件都可以利用 Selector 來拿到狀態,不用在從父元件一直傳一直傳...明天繼續把 HomePage 的代辦清單區塊做出來吧!


上一篇
Day-24 專案演練 - 用跳窗來小試身手 redux
下一篇
Day-26 專案演練 - 在 homePage 拿到 list redux
系列文
新手前端與真實世界的開發 feat.React 與他的夥伴30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言