iT邦幫忙

2024 iThome 鐵人賽

DAY 29
0
Modern Web

現在就學React.js 系列 第 29

React Redux 實作- Day 29

  • 分享至 

  • xImage
  •  

昨日說明了Redux的介紹,今天就要再來準備實作的操作,這次實作也是要把 Day18 的TodoList小作品做個重構,讓原先用 useState 改用成 Redux 的狀態管理,同時加深對 Redux 應用。那今天先就來動手實作吧!

安裝 Redux 和 React-Redux

安裝必要的套件,使用以下命令:

npm install redux react-redux

我們先將 App裡面的 useState 以及 setState 函式邏輯作調整,移動到 todoReducer.js 裡面

// reducers/todoReducer.js

// 定義初始狀態
const initialState = {
  todos: [
    {id: 1, text: '學習 React', completed: false},
    {id: 2, text: '完成作業', completed: false},
  ],
}

// 定義 Reducer
const todoReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return {
        ...state,
        todos: [
          ...state.todos,
          {id: Date.now(), text: action.payload, completed: false},
        ],
      }
    case 'TOGGLE_COMPLETE':
      return {
        ...state,
        todos: state.todos.map(todo =>
          todo.id === action.payload
            ? {...todo, completed: !todo.completed}
            : todo
        ),
      }
    case 'DELETE_TODO':
      return {
        ...state,
        todos: state.todos.filter(todo => todo.id !== action.payload),
      }
    default:
      return state
  }
}

export default todoReducer

reducers/index.js

這個檔案會負責整合所有的 Reducer,這裡目前只有一個 todoReducer

// reducers/index.js
import { combineReducers } from 'redux';
import todoReducer from './todoReducer';

const rootReducer = combineReducers({
  todos: todoReducer,
});

export default rootReducer;

store.js

這個檔案負責創建 Redux 的 store,並匯入 rootReducer

// store.js
import { createStore } from 'redux';
import rootReducer from './reducers';

// 創建 Redux store
const store = createStore(rootReducer);

export default store;

連接 Redux Store 和 React 應用

root.render(
  <React.StrictMode>
    <Provider store={store}>
    <App />
    </Provider>
  </React.StrictMode>
);

在 React 組件中,我們需要存取 Redux store 的狀態,並發送 actions 來更新狀態。這裡會用到兩個關鍵的 React-Redux hooks:useSelectoruseDispatch

// 使用 useSelector 來取得全局狀態
  const {todos} = useSelector(state => state.todos)
  // 使用 useDispatch 來取得 dispatch 方法
  const dispatch = useDispatch()

  // 定義 dispatch action 的方法
  const addTodo = text => {
    dispatch({type: 'ADD_TODO', payload: text})
  }

  const toggleComplete = id => {
    dispatch({type: 'TOGGLE_COMPLETE', payload: id})
  }

  const deleteTodo = id => {
    dispatch({type: 'DELETE_TODO', payload: id})
  }

接著把上述的函式傳遞給組件去做使用

    <Container>
      <GlobalStyle />
      <Title>待辦事項清單</Title>
      <TodoForm addTodo={addTodo} />
      <TodoList
        todos={todos}
        toggleComplete={toggleComplete}
        deleteTodo={deleteTodo}
      />
    </Container>
  )

這樣就完成從 useState 改為 Redux 狀態管理了。

完整程式碼:App.js - nodebox - CodeSandbox

我們實作了一個將 React 應用中的狀態管理從原本的 useState 重構為使用 Redux 的過程。
最後在整理使用Redux狀態管理的好處:

  1. 集中式狀態管理:
    Redux 將應用的所有狀態集中存放在一個全局的 store 中,無論應用的結構多麼複雜,都可以管理和追蹤狀態變更。
  2. 可預測的狀態變更:
    Redux 的設計使每個狀態變更都必須經由 actionreducer,這樣的模式讓狀態變更的邏輯更加明確且容易追蹤。所有的狀態變更都是可預測的,這樣更容易除錯。
  3. 更容易擴展應用:
    在大型應用中,隨著組件和功能的增多,使用 useState 管理狀態可能變得複雜。Redux 的集中式架構讓狀態管理更簡單,也更容易擴展。你可以輕鬆地新增更多 Reducer 和 action 來處理複雜的應用邏輯。
  4. 提高可測試性:
    因為 Redux 將狀態更新邏輯放在純函數 reducer 中,這些函數易於單元測試,確保應用的行為正確無誤。
  5. 更清晰的資料流動:
    在 Redux 中,資料的流動是單向的(單一資料來源),這意味著狀態的變更只會在經過 action 發送和 reducer 更新後發生,避免了像雙向資料綁定這樣的複雜情況。

參考資料:

後記

本文將會同步更新到我的部落格

黃禎平 – Medium


上一篇
React Redux 進階狀態管理工具 - Day28
下一篇
React Redux Toolkit Day30
系列文
現在就學React.js 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言