LoginSignup
0
0

More than 1 year has passed since last update.

Reatの状態管理ライブラリRecoilを触ってみる(Hands-on)

Posted at

はじめに

Reactの状態管理ライブラリRecoilを触ってみました。最初は難しいのかなと思っていたのですが、触ってみるとただのグローバル変数とGetter/Setter使ってるだけじゃん!!ってなりました。知識を落とし込むためにも、Hands-on形式で記事にしております。(ちなみに、Hands-onでは下記成果物ができます。)

Recoilとは

RecoilとはMeta社「旧facebook社」が提供する状態管理ライブラリ。現在は0.7.4版とメジャーリリースがまだですが、機能や安定した利用ができるようです。
スクリーンショット 2022-06-24 19.24.09.png

Hands-on開始

ディレクトリ
~/develop/react/recoil/recoil_counter $ tree -I node_modules                                      
.
├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
├── src
│   ├── App.css
│   ├── App.test.tsx
│   ├── App.tsx                           ←修正
│   ├── Counter.tsx                ←作成
│   ├── atom.ts                           ←作成
│   ├── index.css
│   ├── index.tsx
│   ├── logo.svg
│   ├── react-app-env.d.ts
│   ├── reportWebVitals.ts
│   └── setupTests.ts
├── tsconfig.json
└── yarn.lock

2 directories, 21 files
プロジェクト作成
~/develop/react/recoil/recoil_counter $ yarn create react-app recoil_counter --template typescript
yarn add recoil

ソースコードの中身

App.tsx
import { FC} from 'react'
import { RecoilRoot } from 'recoil'
import Counter from './Counter'


const App: FC = () => {
  return (
    <div>
      <RecoilRoot>
          <div>
            <Counter />
          </div>
      </RecoilRoot>
    </div>
  )
}

export default App

→Recoilを利用する場合、RecoilRootで囲う必要があります。

atom.ts
import { atom, selector } from "recoil"

// グローバル変数のcounterAtom
export const counterAtom = atom({
    key: 'counterAtom',
    default: 0,
  })

// グローバル変数のGetter/Setter 
export const counterSelector = selector<number>({
    key: 'counterSelector',
    get: ({ get }) => {
      const counter = get(counterAtom)
      return counter
    },
    set: ({ set }, newValue) => {
      set(counterAtom, newValue)
    },
  })

→Recoilのライブラリからatomselectorをimportしています。
atomはただのグローバル変数、selectorはグローバル変数のGetter/Setterと考えるとわかりやすいでしょう。

Counter.tsx
import { FC, memo } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
import {counterAtom, counterSelector } from './atom'

const Counter: FC = memo(() => {
  const countValue = useRecoilValue(counterAtom) //グローバル変数を直接取得
  const [count, setCount] = useRecoilState(counterAtom) // グローバル変数を他の変数に代入し取得
  const [counter, setCounter] = useRecoilState(counterSelector) // グローバル変数のSelector経由で取得

  const handleClickCount = (count: number) => {
    setCount(count)
  }

  return (
    <>
      <h1>カウンターアプリ(Recoilで状態管理)</h1>
      <div className="div">
        <h2>カウント値</h2>
        <span>{countValue}</span>
      </div>
      <div className="div">
        <div>
          <h2>グローバル変数を直接変更!!!</h2>
        </div>
        <div>
          <button onClick={() => handleClickCount(count - 1)}>-</button>
          <span>{count}</span>
          <button onClick={() => handleClickCount(count + 1)}>+</button>
        </div>
      </div>
      <div className="div">
        <h2>グローバル変数のSelector経由で取得!!!</h2>
        <div>
          <button onClick={() => setCounter(counter - 2)}>-</button>
          <span>{counter}</span>
          <button onClick={() => setCounter(counter + 2)}>+</button>
        </div>
      </div>
    </>
  )
})

export default Counter

触ってみると意外と素直なやつなんでした。

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