昨日說明了Redux的介紹,今天就要再來準備實作的操作,這次實作也是要把 Day18 的TodoList小作品做個重構,讓原先用 useState  改用成 Redux 的狀態管理,同時加深對 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:useSelector 和 useDispatch。
// 使用 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狀態管理的好處:
action 和 reducer,這樣的模式讓狀態變更的邏輯更加明確且容易追蹤。所有的狀態變更都是可預測的,這樣更容易除錯。useState 管理狀態可能變得複雜。Redux 的集中式架構讓狀態管理更簡單,也更容易擴展。你可以輕鬆地新增更多 Reducer 和 action 來處理複雜的應用邏輯。reducer 中,這些函數易於單元測試,確保應用的行為正確無誤。本文將會同步更新到我的部落格