Blogブログ

【React】状態管理のライブラリ、Recoil使ってみた。

こんにちは、HLCのエンジニアの掛橋です。
Reactの開発で状態管理はRedux,Context,自作hooksなど様々な管理方法がありますが
個人的におすすめなRecoilについてご紹介します。

Recoilとは

https://recoiljs.org/
Meta社(旧Facebook)が開発しているReactの状態管理ライブラリです。
Recoliには大きく2つの概念があります。
AtomSelectorです。
Atomは状態を管理します。状態の保持と状態の更新ができます。
SelectorはAtomで管理している状態を加工して取得することができます。

(※今回の記事ではAtomの使い方を紹介します。Selectorに関してはまた別の記事で!)

Recoil Atomの使い方

、子、孫のコンポーネントがあり、孫にあるボタンをクリックすると親にある数が増えるという機能を実装します。

ファイル構成は以下の様になっています。
App.tsxはコンポーネント<Parent/>を持つ。
Parent.tsxはコンポーネント<Child/>を持ち、カウントアップする数字を表示しています。
Child.tsxはコンポーネント<GrandChild/>を持つ。
GrandChild.tsxは数値を更新するボタンがあります。

1.状態管理をしたいコンポーネントの最上位層をRecoilRootで囲う


import { RecoilRoot } from "recoil"
import { Parent } from "./components/Parent"
export const App = () => {
  return (
     <RecoilRoot>
      <div>
        <Parent />
      </div>
    </RecoilRoot>
  )
}

2.Atomファイルの作成


export const numAtom = atom({
  key: "numAtom",
  default: 0,
})

keyは他のAtomと被らないように必ず一意であることに気をつけましょう。
defaultには初期値を入れます。今回は0を入れています。

3.Atomからstateを読み取る


import { useRecoilState } from "recoil"
import { numAtom } from "../Atoms/NumAtom"
import { Child } from "./Child"
export const Parent = () => {
  const [num, setNum] = useRecoilState(numAtom)
  return (
      <div style={{ backgroundColor: "#FF4F02", padding: 30 }}>
        <div style={{ fontSize: "40px" }}>{num}</div>
        <div>親</div>
        <Child />
      </div>
  )
}


useRecoilStateの引数に1.で準備したAtomを入れることで
[Aromの値、Atomの値を変更するメソッド]というタプルが返ってきます。
useStateみたいで使いやすいですよね。

4.Atomのstateを変更する


import React from "react"
import { useRecoilState } from "recoil"
import { numAtom } from "../Atoms/NumAtom"

export const GrandChild = () => {
  const [num, setNum] = useRecoilState(numAtom)
  const countUp = () => {
    setNum((num) => num + 1)
  }
  return (
      <div style={{ backgroundColor: "#FFDBC9", margin: 30, padding: 30 }}>
        <div>孫</div>
        <div>
          <button onClick={countUp}>+1</button>
        </div>
      </div>
  )
}


ボタンをクリックすることで、countUpメソッドが走ます。
countUpメソッド内ではuseRecoilStateの更新関数(setNum)を実行させ、Atomの値を変更します。

Contextを使えばいいのでは?

Reactで準備されているContextを使えばいいのでは?と思うかもしれませんが
Recoilにはあるが、Contextにはない”強み”があります。
それは不要な再レンダリングを発生させずに値を更新できること、、!!!
useRecoilStateを使うと、RecoilRootで囲まれた要素は全て再レンダリングが走ってしまうのですが
useRecoilValue、useSetRecoilStateというものを扱うことで全て再レンダリングされることを防ぐことができます!

次回の記事ではその強みについてご説明させていただきます!お楽しみに!

掛橋

執筆者

Developer

掛橋