這是什麼

useReducer()是 React Hooks API 中的一個方法,與useState類似,但為您提供了更多控制權來管理狀態。它接受一個reducer函數和初始狀態作為參數,並傳回狀態和調度方法:

const [state, dispatch] = React.useReducer(reducerFn, initialState, initFn);

reducer(之所以這樣稱呼,是因為您將傳遞給陣列方法Array.prototype.reduce(reducer, initialValue)函數類型)是取自 Redux 的模式。如果您不熟悉 Redux,簡而言之,reducer 是一個純函數,它將先前的狀態和操作作為參數,並傳回下一個狀態。

(prevState, action) => newState

操作是描述發生的事情的一條訊息,並且根據該訊息,reducer 指定狀態應如何變更。動作透過dispatch(action)方法傳遞。

使用它的 3 個理由

大多數時候,您只需使用useState()方法就可以了,該方法建立在useReducer()之上。但有些情況下useReducer()較可取。

下一個狀態取決於上一個狀態

當狀態依賴前一個方法時,使用此方法總是更好。它會給你一個更可預測的狀態轉換。簡單的例子是:

function reducer(state, action) {
  switch (action.type) {
    case 'ADD': return { count: state.count + 1 };
    case 'SUB': return { count: state.count - 1 };
    default: return state;
  }
}

function Counter() {
  const [state, dispatch] = React.useReducer(reducer, { count: 0 });
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'ADD'})}>Add</button>
      <button onClick={() => dispatch({type: 'SUB'})}>Substract</button>
    </>
  );
}

複雜狀態形狀

當狀態包含多個原始值時,例如巢狀物件或陣列。例如:

const [state, dispatch] = React.useReducer(
  fetchUsersReducer,
  {
    users: [
      { name: 'John', subscribred: false },
      { name: 'Jane', subscribred: true },
    ],
    loading: false,
    error: false,
  },
);

管理這種本地狀態更容易,因為參數相互依賴,並且所有邏輯都可以封裝到一個reducer中。

易於測試

reducer是純函數,這意味著它們沒有副作用,並且在給定相同參數的情況下必須返回相同的結果。測試它們更容易,因為它們不依賴 React。讓我們從計數器範例中取得一個reducer並使用模擬狀態對其進行測試:

test("increments the count by one", () => {
  const newState = reducer({ count: 0 }, { type: "ADD" });
  expect(newState.count).toBe(1)
})

結論

useReducer()useState()的替代方法,它使您可以更好地控制狀態管理並使測試更容易。所有情況都可以使用useState()方法來完成,因此總而言之,使用您熟悉的方法,並且對您和同事來說更容易理解。


原文出處:https://dev.to/spukas/3-reasons-to-usereducer-over-usestate-43ad


共有 0 則留言