loading...
上次更新: 2023-06-04
useState 來操作 state。我們也可以用 useReducer 做到一樣的事,useReducer 適合較複雜的 state。useState 的狀態改變會分散在不同的函式裡面;而透過 useReducer,我們可以將狀態的改變統一做管理。Demo: https://codesandbox.io/s/usereducer-uw68c6?file=/src/App.js
export default function App() {
const increment = () => {};
const decrement = () => {};
return (
<div className="App d-flex">
<button onClick={decrement}>-</button>
<div className="m-4">// 計數器的值</div>
<button onClick={increment}>+</button>
</div>
);
}useReducer() 會接收2個參數:
useState() 的初始值一樣,不過 useReducer 是用在較複雜的 state 處理,所以通常不會是單純數字、字串等,因此範例中用 {count: 0}。// reducer 函式
const reducer = () => {};
export default function App() {
// 創建 useReducer()
const [] = useReducer(reducer, { count: 0 });
const increment = () => {};
const decrement = () => {};
return (
<div className="App d-flex">
<button onClick={decrement}>-</button>
<div className="m-4">// 計數器的值</div>
<button onClick={increment}>+</button>
</div>
);
}我們要在 reducer 裡面做運算,並 return 新的狀態。
reducer() 有兩個參數:
{count: 0}type 屬性的物件。(詳見 step4)const reducer = (state, action) => {
return { count: state.count + 1 };
};
export default function App() {
const [] = useReducer(reducer, { count: 0 });
const increment = () => {};
const decrement = () => {};
return (
<div className="App d-flex">
<button onClick={decrement}>-</button>
<div className="m-4">{state.count}</div>
<button onClick={increment}>+</button>
</div>
);
}useReducer() 會回傳一個 array,array 裡有兩個項目:
reducer function。reducer() 的 action。code 說明:
以下範例中,點擊 + 按鈕,會執行 dispatch(),而 dispatch 會呼叫 reducer。
在 reducer 中,把當前 count 加ㄧ,並更新狀態。
const reducer = (state, action) => {
console.log(action); // 印出 { tpye: "plus" }
return { count: state.count + 1 };
};
export default function App() {
// 回傳值為 [狀態, dispatch 函式]
const [state, dispatch] = useReducer(reducer, { count: 0 });
const increment = () => {
// 接收的參數會是 reducer 的 action
dispatch({ type: 'plus' });
};
const decrement = () => {};
return (
<div className="App d-flex">
<button onClick={decrement}>-</button>
<div className="m-4">{state.count}</div>
<button onClick={increment}>+</button>
</div>
);
}在 step3,我們點擊 + 時會把 count 加一,那麼減要如何實作呢?
+ 時,呼叫 dispatch 並傳入 action {type: 'plus'}- 時,也呼叫 dispatch ,並傳入另一個 action {type: 'minus'}reducer 裡,判斷 action type 為 plus 或 minus,來做相對應的動作。const reducer = (state, action) => {
// 判斷 action type,執行相對應的動作
switch (action.type) {
case "plus":
return { count: state.count + 1 };
case "minus":
return { count: state.count - 1 };
default:
return state;
}
};
export default function App() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
const increment = () => {
// 傳入 `加` 的 action
dispatch({ type: "plus" });
};
const decrement = () => {{
// 傳入 `減` 的 action
dispatch({ type: "minus" });
};
return (
<div className="App d-flex">
<button onClick={decrement}>-</button>
<div className="m-4">{state.count}</div>
<button onClick={increment}>+</button>
</div>
);
}plus minus 字串const ACTIONS = {
PLUS: 'plus',
MINUS: 'minus',
};
const reducer = (state, action) => {
switch (action.type) {
case ACTIONS.PLUS:
return { count: state.count + 1 };
case ACTIONS.MINUS:
return { count: state.count - 1 };
default:
return state;
}
};
export default function App() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
const increment = () => {
dispatch({ type: ACTIONS.PLUS });
};
const decrement = () => {
dispatch({ type: ACTIONS.MINUS });
};
return (
<div className="App d-flex">
<button onClick={decrement}>-</button>
<div className="m-4">{state.count}</div>
<button onClick={increment}>+</button>
</div>
);
}參考資料: