0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React】useReducerの基礎と使い所

Posted at

業務でuseReducerを初めて使う機会があったので、簡単にまとめておきます。

useReducerとは

useReducerは、リデューサ (reducer) をコンポーネントに追加するための React フックです。
※reducerとは、コンポーネントの外部に、単一の関数にすべての state 更新ロジックを集約した関数のこと。(直訳すると、reduce=減らす)

useStateとの違い

シンプルな文字列や数値、真偽値であれば、useStateが適していますが、オブジェクトや配列、また、変更パターンが複雑な場合はuseReducerが適しています。

https://ja.react.dev/reference/react/useReducer より引用

基本的な使い方

const [state, dispatch] = useReducer(reducer, initialArg, init?)

それぞれの値は、下記の役割となっています。

  • state: 管理する値
  • dispatch: reducer を呼び出すための関数
  • reducer: stateを更新するための関数。引数にstateとactioinをとり、更新されたstateを返す。actionとは何をするかを示すオブジェクト。
  • initialArg: state初期値
  • init: 省略可能。state初期値を返す関数。指定されていない場合、初期 state は initialArg そのものになる

例題としてよく使われるカウンターを例にしてみたいと思います。

stateが数値の場合

const initialState = 0;
const [count, dispatch] = useReducer(reducer, initialState)
  • dispatch
<Button onClick={()=>dispatch('increment')}>+1</Button>
<Button onClick={()=>dispatch('decrement')}>-1</Button>
  • reducer
const reducer = (count, action)=> {
switch (action){
  case 'increment':
    return count + 1
  case 'decrement':
    return count - 1
  default:
    return count
  }
}

stateがオブジェクトの場合

const initialState = {
    countA: 0,
    countB: 0
};
const [countState, dispatch] = useReducer(reducer, initialState)
  • dispatch
<Button onClick={()=>dispatch('incrementA')}>+1</Button>
<Button onClick={()=>dispatch('decrementA')}>-1</Button>
<Button onClick={()=>dispatch('incrementB')}>+10</Button>
<Button onClick={()=>dispatch('decrementB')}>-10</Button>
  • reducer
const reducer = (countState, action)=> {
switch (action){
  case 'incrementA':
    return {...countState, countA: countState.countA + 1}
  case 'decrementA':
    return {...countState, countA: countState.countA - 1}
  case 'incrementB':
    return {...countState, countB: countState.countB + 10}
  case 'decrementB':
    return {...countState, countB: countState.countB - 10}
  default:
    return count
  }
}

payloadを使う

dispatch関数側から、actionだけでなく、値を渡したいケースがあるかもしれません。payloadを使うことで実現できます。

  • dispatch
<Button onClick={()=>dispatch({type: 'increment', payload: 5})}>increment</Button>
<Button onClick={()=>dispatch({type: 'decrement', payload: 5})}>decrement</Button>
  • reducer
const reducer = (count, action)=> {
switch (action){
  case 'increment':
    return {count: state.count + action.payload}
  case 'decrement':
    return {count: state.count - action.payload}
  default:
    return count
  }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?