こんにちはフロントエンドエンジニアのまさにょんです!
今回は、Reactの状態管理ツールであるRecoilのstateとHooks(atom, selector, useRecoilState)の使い方について解説していきます。
目次
Recoilのstate(atom, selector)の定義方法・使い方
Recoilの基本は、AtomによるState(状態)の定義です。
AtomでState(状態)を定義する
Recoilではatomを利用して共有したい状態(State)の定義を行います。
atomは複数設定することができ、個々のatomは独立した状態(State)を持ちます。
atomでは、Objectのkeyプロパティに一意となる名前、defaultプロパティに初期値を設定します。
keyプロパティは、アプリケーション内のatomの中で一意となるように設定する必要があるので、注意が必要です。
import { atom } from 'recoil';
// Loginを管理するフラグ
export const isLogined = atom<boolean>({
key: 'isLogined',
default: false,
});
selectorを使って、atomを使った計算処理・更新処理をする
selectorはatomの状態を操作したい場合(atomの値を利用して別の処理を行う)に利用することができます。
つまり、atom(State)を使って、何か計算したり、データ処理をするのに使えるわけです。
selectorはatomと同様にkeyプロパティで一意の名前をつける必要がありますがatomとは違い、初期値の設定は必要ありません。
selectorでは、defaultの代わりにgetプロパティや、setプロパティを設定することができます。
getプロパティのget関数はselectorの中のみで利用することができ、atomやselectorにアクセスすることができます。
また、setプロパティのset関数を利用して、atomの値を更新することもできます。
import { atom, selector } from 'recoil';
// Loginを管理するState
export const isLogined = atom<boolean>({
key: 'isLogined',
default: false,
});
// Adminを管理するState
export const isAdmin = atom<boolean>({
key: 'isAdmin',
default: false,
});
// 1. selector は、 get関数 や set関数を内部に持つことができる。
// 2. get関数なら、AtomのStateを取得して、そこから計算した結果を返すなとができる。
// 3. set関数なら、AtomのStateを更新することができる。
// AdminUser, LoginUser, NoLoginUser で、それぞれstatusCodeを分ける処理
export const userStatus = selector({
key: 'userStatus',
get: ({ get }) => {
const isLogined = get(isLogined);
const isAdmin = get(isAdmin);
let statusCode = 0;
if (isLogined) {
statusCode = 1;
}
if (isAdmin) {
statusCode = 2;
}
return statusCode;
}
});
Recoilの提供するHooks
先述した、atomで定義した状態(State)には、直接アクセスするのではなくRecoil 独自の Hooks を利用する必要があります。
ここからは、Recoilの提供するHooksの一部を紹介していきます。
useRecoilValue: atomからvalue(state)だけを取得するためのHook
useRecoilValue()
は、atomからvalue(state)だけを取得したい場合に使います。
つまり、このHookは、Setter関数 を提供しないで、value(state)だけを提供します。
通常、 write しない(readonly)意思を明確にしたい時に使用します。
write もしたい場合は代わりに useRecoilState()
を使用します。
Recoil state が変化したとき、コンポーネントは再描画されるので、get ではなく subscribe していると考えるといいです。
使い方は、useRecoilValue(atomエイリアス)
の形で、value(state)を取得することができます。
import { useRecoilValue } from 'recoil';
import { isLogined } from '@/states/userManagement'; // atom定義をimport
// useRecoilValue(atomエイリアス) で、valueを取得できる。
if (useRecoilValue(isLogined)) {
console.log('ログインしています');
} else {
console.log('ログインしていません');
}
useSetRecoilState:atomからSetterだけを取得するためのHook
useSetRecoilState()
は、 atomからSetterだけを取得したい場合に使います。
つまり、このHook は value そのものを提供しないで、Setter関数だけを提供します。
コンポーネントが value に依存しないので、value が変化しても再描画されない(再描画コストを抑えられる)などのメリットもあります。
使い方は、const setter = useSetRecoilState(更新したいatomエイリアス);
のような形でSetter関数を作成できます。
import { useSetRecoilState } from 'recoil';
import { isLogined } from '@/states/userManagement'; // atom定義をimport
// const setter = useSetRecoilState(atomエイリアス);
const setIsLogined = useSetRecoilState(isLogined);
setIsLogined(true);
useRecoilState: atomからvalueとSetter関数、両方を取得するためのHook
useRecoilState()
は、atomからvalueとSetter関数、両方を取得したい場合に使います。
つまり、Recoil state(Atom) から value と setter の両方を取り出す時に使う Hookです。
これは、先述の useRecoilValue と useSetRecoilState を合わせた Hookです。
const [ value, setter ] = useRecoilState(atomエイリアス);
のような形で定義して使います。
これは React.useState
と同じインターフェイス(タプル)です。
import { useRecoilState } from 'recoil';
import { isLogined } from '@/states/userManagement'; // atom定義をimport
const [isLogined, setIsLogined] = useRecoilState(isLogined);
Twitterやってます!Follow Me!
神聖グンマー帝国の逆襲🔥
神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!