deve.K

エンジニアが未来を切り開く。

React useReducerフックとは 使い方

react画像

本日はReact.jsのuseReducerフックの解説をしていきます。

『useReducer』はフックの中でも、非常に高度なフックの1つとなっています。

React初心者に関しては実際に使用方法をよく知らない場合がほとんどです。

ですが、このフックはより適切で明確なコードを作成するのに非常に皆様の役に立ってくれるはずです。

是非覚えて今回で『useState』の勉強から1ランク上へいきましょう。

useStateフックに関する学習は下記になります。

dev-k.hatenablog.com

useReducerとは

『状態』管理フックとして『useState』これは、

コンポーネントの状態を管理できるようにするフックです。

ただし、『useReducer』フックの動作方法は『useState』とはかなり異なります。

代替え品というものです。

これはReact Docs(ドキュメント)もuseReducerフックがuseStateフックの代替えであると示唆しています。

ja.reactjs.org

どう言った場合に活用するのか

『useReducer』はコンポーネントの階層が深く、複雑な状態を持ち多くの異なる状態を管理していかなければならない、または以前の状態を元に新しい状態として作る場面での時に使用されます。

最上位のコンポーネントで参照されている状態が、何百個もあった場合あなたは簡単にそれらを把握することはできますか?

アプリケーションが複雑になるにつれて、状態ツリーはすぐに手に負えなくなる可能性があります。

そのような、複雑さに対処するために提供された最良のパターンの1つがレデューサーとなります。

最上位コンポーネントから任意のコンポーネントに渡すことができます。

これを最上位コンポーネントで定義し、状態をグローバルにすることができます。

そしてすべての状態を管理し1つのオブジェクトによってまとめることができます。

状態を1つのオブジェクトとしてまとめる?

Reduxですか?

気付いた方はいらっしゃるかと思います。

はい、つまり特定のアクション(動作)がディスパッチされたときにコンポーネントの状態の一部を更新できます。

これは『Redux』の動作と非常によく似ております。

ですが、状態は常にオブジェクトである必要はなく制限はありません。

『配列』や『数値』でも構いません。

『useReducer』のレデューサーはReduxからのものであり、

『Redux』はJavaScriptの『Array.reduce()』から借用しているのです。

ですので、JavaScriptのMDNでreduce()について最初から参照されているチュートリアルに戻って学習してみて下さい。

developer.mozilla.org

これまでの開発者の間で最も人気のあるフックの1つはこの『useReducer』とも言えます。

比較

const [state, setState] = useState(value);

const [state, dispatch] = useReducer(reducer, 0);

上記の通り、どちらもこのフックは2つの要素を持つ配列を返します。

useReducerの引数はレデューサー関数と2つの引数を使用してフックを呼び出し、2つ目が初期状態となります。

useReducerフックでは『状態』と『dispatch』と呼ばれる新しい特別な関数を返すフックという事になります。

ほぼ『useState』に近いです。

しかし、レデューサーは3番目の引数もあると言う事も知っておいて下さい。

const [state, dispatch] = useReducer(reducer, 0, init);

上記では3番目の引数があります。

これは 初期状態を遅延的に作成するオプションの値となります。

外部の関数を使用して初期状態の値を計算できます。

useReducerフックは基本的に、関数コンポーネントがアプリケーションの状態管理からレデューサー機能にアクセスできるようにします。

なんとなく機能は理解できましたでしょうか?

では機能の扱い方を見ていきましょう。

よくある、カウンターコンポーネントでの簡単な例での解説になります、流れをご確認下さい。

useReducer使用例

まずは全体コードをどうぞ

import { useReducer } from 'react';

const App = () => {

const [count, dispatch] = useReducer(myReducer, 0);

const myReducer = (state, action) => {

    switch(action) {

      case 'INCREMENT':

      return state + 1

      case 'DECREMENT':

      return state - 1

      default:
        throw new Error()
    }
    }
  return(
    <div >
      <header className='App-header'>
      <p>Counter: {count}</p>

<button onClick={() => dispatch('INCREMENT')}>+</button>

<button onClick={() => dispatch('DECREMENT')}>-</button>

      </header>
    </div>
  )
}

export default App;

DEMO

reactGIF画像

上記は、初期状態である( 0 )の値を使用して新しい値を計算する方法を示しております。

では分割しながら解説致します。

import { useReducer } from 'react';

しっかり読み込まれるように、インポートをしましょう。

const App = () => {

const [count, dispatch] = useReducer(myReducer, 0);

}

レデューサーは『状態』と『動作』2つの引数を取るので現在の状態の値は『 0 』となります。

基本的に、レデューサーは状態の変更を管理する機能にすぎません。

なので『useState』を理解してれば、レデューサーはそこまで難しいフックではないんです。

const myReducer = (state, action) => {

    switch(action) {

      case 'INCREMENT':

      return state + 1

      case 'DECREMENT':

      return state - 1

      default:

        throw new Error()
    }
    }

『useReducer』はSwitch文を使用される事が多いです。

『dispatch』を呼び出すときに指定される引数は、上記ではmyReducer関数の( action )に指定されている2番目の引数となります。

dispatch関数を使用して、現在の状態を暗黙的に変更する動作をレデューサーに送信可能です。

レデューサーは状態と動作を実行する関数であるので任意での値にすることが可能となります。

上記では文字列となっており『DECREMENT』で『カウンター』を1ずつ減らしていきます。

『INCREMENT』は増加なので数が増えていきます。

そしてレデューサーは動作を実行した後に新しい『状態』を返します。

それは、以前の状態を元に新しい状態として作っているという事です。

  return(
    <div >
 <header className='App-header'>

      <p>Counter: {count}</p>

<button onClick={() => dispatch('INCREMENT')}>+</button>

<button onClick={() => dispatch('DECREMENT')}>-</button>

      </header>
    </div>
  )

dispatchの唯一の仕事は動作を実行し、それらをレデューサーに送信することです。

状態に応じて、レデューサー関数に対して正しい動作がdispatchされます。

その後、Reactコンポーネントが再度レンダリングされますが、useReducerフックからの新しい状態が使用される事になります。

Reduxは必要ないのか?

useReducerフックの導入によって、Reduxのような外部ライブラリを導入することなく、相当な量の複雑な状態を管理できるようになったのは事実です。

すべてのuseReducer状態を取得し、トップレベルのコンポーネントに配置した場合、Reduxはもう必要ないように感じるかもしれません。

ですが、これはReduxが役に立たないという意味ではありません、Reduxには検討するべき価値のある他の機能や利点がまだたくさんございます。

useReducerがReduxの動作と非常に似ているように見えても、それでもReduxではありません。

このuseReducerフックは、より複雑なアプリケーションではReduxやMobXに置き換わるものではございません。

ですが、単純なアプリケーションではuseReducerフックがReduxを置き換えることができると思います。

Reduxは、グローバルな状態を必要とする大きくて複雑なアプリケーションで作業する必要がある場合、ほとんどのReact開発者にとって頼りになります。

より複雑なアプリの場合は、Reduxのような状態管理ライブラリが引き続き必要になる事は間違いありません。

最後に

レデューサーで従うべき重要なルールの1つは、関数に渡される引数は変更されないままである必要性があります。

同じ引数が渡された場合、関数は常に同じ出力を返します。

そしてレデューサー関数は副作用を引き起こしません。

useReducerフックを早く理解したいのであれば、『dispatch』を先に理解すれば、自ずと分かってきます。

useReducerはuseStateとほぼ変わりませんが、ですがむやみやたらと使用するのは避けましょう。

使い分けて、なるべく『useState』を使用していき問題が起きた時は『useReducer』で代替えして下さい。

useReducerフックは、React.js用のReduxを必要としない小規模および中規模のアプリケーションに最適となります。

そしてuseReducerを理解できれば、Reduxの学習時の理解も簡単となる事でしょう。

本日は以上となります。

最後までお読み頂きありがとうございました!。

プライバシーポリシー