LoginSignup
0
1

More than 1 year has passed since last update.

Recoil使い方(要修正) 個人メモ

Last updated at Posted at 2022-05-29

Recoilとは

  • グローバルステートを管理するFacebookが開発しているライブラリ

使い方

  • npm install recoil でRecoilをインストール
  • Reduxでいう<provider>のようにして<RecoilRoot>で囲む
ReactDOM.render(
  <RecoilRoot>
    <App/>
  </RecoilRoot>,
  document.getElementById('root')
);
  • atomuseRecoilStateをインポートする
import { atom, useRecoilState } from "recoil"; 
  • atom関数を使用してuseRecoilStateに必要なパーツ(引数)を作成
const countState = atom<number>({ 
  //ユニークキー
  key: "simple/counter", 
  //初期値
  default: 0 
});
  • useRecoilStateにstateを引数として入れる
// 変数と関数を同時生成
const [count, setCount] = useRecoilState<number>(countState)
// 関数のみ生成
const setCount = useSetRecoilState<number>(countState)
// 変数のみ生成
const count = useRecoilValue<number>(countState)
  • setCountでstateを更新する
<button onClick={() => setCount((c) => c + 1)}>Clicked : {count}</button>

全体像

import React from 'react'
import { atom, useRecoilState } from 'recoil'

//stateに必要なパーツ(引数)atom関数を使用
const countState = atom<number>({
  //ユニークキー
  key: 'simple/counter',
  //初期値
  default: 0,
})

export const Footer: React.FC = () => {
  // useRecoilStateにぶち込む
  const [count, setCount] = useRecoilState<number>(countState)
  return (
    <>
      <p>Footer</p>
      <button onClick={() => setCount((c) => c + 1)}>Clicked : {count}</button>
    </>
}

Selector関数

  • atomのstateを加工することが可能
  • 複数のatomのセットが可能(やり方不明)
const reCountState = selector<number>({
  //ユニークキー
  key: 'simple/reCounter',
  //atomで作ったstateを3倍に加工する(getはあくまで値を読み取る用)
  get: ({ get }) => get(countState) * 3,
  //setは値の加工で任意で追加
  set: ({ get, set }, newValue) => {
    if (typeof newValue == 'number') {
      set(countState, newValue * 3)
    }
  },
})
  • selector関数で作ったstateで変数と関数を生成
//selectorで変数と関数を生成
const [reCount, setCount] = useRecoilState<number>(reCountState)

selector、atom、set関数の処理の順序

atomで指定してある初期値を取得して表示
selectorを介して生成されたstateの値は、atomの値を参照した後getメソッドの処理が走った上で表示される
③ set関数で値をセットする
selectorで設定されているsetメソッドの処理が走り、stateが更新される
⑤ ①に戻る

//state生成に必要なatom関数を使用
const countState = atom<number>({
  //ユニークキー
  key: 'simple/counter',
  //初期値
  default: 0,
})

//atomの値を加工するselector関数
const reCountState = selector<number>({
  //ユニークキー
  key: 'simple/reCounter',
  //② atom関数で生成したstateの変数を3倍に加工する(※1回目の処理後 3 *2回目の処理後 12)
  get: ({ get }) => get(countState) * 3,
  //setの方もgetの順番と同じっぽい
  set: ({ get, set }, newValue) => {
    if (typeof newValue == 'number') {
      set(countState, newValue * 3)
    }
  },
})

export const Footer: React.FC = () => {
  //atom関数で生成したstateから変数のみ生成
  const [count] = useRecoilState<number>(countState)

  //selector関数で生成したstateで変数と関数を生成
  const [reCount, setCount] = useRecoilState<number>(reCountState)

  return (
    <>
      {/*① set関数で +1 される(※1回目の処理後 1 *2回目の処理後 4) 
         ③ selectorで加工された値がset関数の引数に入る(※1回目の挿入値(初動は加工されない) 0 ※2回目の挿入値 3)*/}
      <button onClick={() => setCount((c) => c + 1)}>atom counter</button>
      <p>atom:{count}</p>
      <p>selector:{reCount}</p>
    </>
  )
}

動的にAtomを生成する

  • atomFamily関数というもので識別子をつけられる
//atomFamily関数でstateを作成(作成したstateは関数として使う)
const itemStateFamily = atomFamily<number, SerializableParam>({
  key: 'atomfamily',
  default: 0,
})

//生成した関数に識別子を渡す
const atom = itemStateFamily("My name")
//上記の変数を使って関数・変数を作成
const [state, setState] = useRecoilState(atom)
  • atomと違う要素としてdefaultに関数を指定できる
const numStateFamily = atomFamily<number, number>({
  key: 'atomfamily',
  //識別子として渡したものがここに入る??
  default: (i) => i * 5,
})

//defaultに設定した関数の引数に今回の引数が入る
const numAtom = numStateFamily(numName)

動的にSelectorを生成する

export const selectorFamilySample = selectorFamily<number, string>({
  key: 'selector-family',
  get:
    (arg) =>
    ({ get }) => {
      return get(itemStateFamily(arg))
    },
  set:
    (arg) =>
    ({ set }, value) => {
      console.log('value')
      console.log(value)
      if (typeof value == 'number') set(itemStateFamily(arg), value * 3)
    },
})

他コンポーネントからの呼び出し

  • useRecoilStateに必要な引数であるatom関数やselector関数で作ったstateをexportして外部で使う
  • 関連してるstateは更新されると全て再レンダリングが走る
import { countState } from '../RecoilStart/RecoilStart'

export const StateCall: React.FC = () => {
  const [callState, setCallState] = useRecoilState<number>(countState)

  return (
    <>
      <button onClick={() => setCallState((c) => c + 1)}>
        別コンポーネントで呼び出し
      </button>
      <p>call:{callState}</p>
    </>
  )
}

参考記事

0
1
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
1