# 簡述 useReducer 語法:`const [state, dispatch] = useReducer(reducer, initialArg, init);` - `useReducer` 第一個參數用來設定變更 state 的規則,特定的 action 時如何更新 state - `useReducer` 第二個參數是初始化的 state - `useReducer` 第三個參數是初始化 state 的函式,非必要的參數,用來抽出`initialArgs` 的計算邏輯 - dispatch 用來觸發 action ```jsx= import React, { useReducer } from "react"; // 初始化 state const initialState = { count: 0 }; function reducer(state, action) { switch (action.type) { case "increment": return { count: state.count + 1 }; case "decrement": return { count: state.count - 1 }; case "reset": return { count: (state.count = 0) }; default: return { count: state.count }; } } export default function App() { const [state, dispatch] = useReducer(reducer, initialState); return ( <div> Count: {state.count} <br /> <br /> <button onClick={() => dispatch({ type: "increment" })}>Increment</button> <button onClick={() => dispatch({ type: "decrement" })}>Decrement</button> <button onClick={() => dispatch({ type: "reset" })}>Reset</button> </div> ); } ``` [example code](https://codesandbox.io/s/crimson-browser-xm3nh) ## 第三個參數 As far as I can experiment, the `init` function as third arg is a transformer of the `initialState`. It means that `initialState` will not be used a initial state, but as argument for `init` function. The return of this one will be the true `initialState`. It could be useful to avoid huge parameter during the `useReducer` initialization line. - code ```jsx= function init(initialCount) { return {count: initialCount}; } function reducer(state, action) { switch (action.type) { case 'increment': return {count: state.count + 1}; case 'decrement': return {count: state.count - 1}; case 'reset': return init(action.payload); default: throw new Error(); } } function Counter({initialCount}) { const [state, dispatch] = useReducer(reducer, initialCount, init); return ( <> Count: {state.count} <button onClick={() => dispatch({type: 'reset', payload: initialCount})}> Reset </button> <button onClick={() => dispatch({type: 'decrement'})}>-</button> <button onClick={() => dispatch({type: 'increment'})}>+</button> </> ); } ``` # 參考資料 [Day6-React Hook 篇-useReducer - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天](https://ithelp.ithome.com.tw/articles/10268258?sc=hot) [What's the purpose of the 3rd argument in useReducer?](https://stackoverflow.com/questions/59041341/whats-the-purpose-of-the-3rd-argument-in-usereducer)