昨日說明了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
中,這些函數易於單元測試,確保應用的行為正確無誤。本文將會同步更新到我的部落格