Recoil と Local Storage のデータを共有させる方法 (2023年5月18日)
高橋
使用するライブラリ
Recoil とは
Facebook 製(現 Meta 社)の React 用の状態管理ライブラリです。
実装内容
まずはこちらが全体のコードです。
import { atom } from "recoil";
const LOCAL_STORAGE_KEY = "LOCAL_STORAGE_KEY";
const getToLocalStorage = () => {
if (typeof window === "undefined") {
return "";
}
const value = window.localStorage
.getItem(LOCAL_STORAGE_KEY);
return value ? JSON.parse(value) : "";
};
const saveToLocalStorage = (value: string) => {
if (typeof window === "undefined") {
return;
}
window.localStorage
.setItem(LOCAL_STORAGE_KEY, JSON.stringify(value));
};
export const recoilWithLocalStorage = atom<string>({
key: "recoilWithLocalStorage",
default: getToLocalStorage(),
effects_UNSTABLE: [
({ onSet }) => {
onSet((newValue) => {
saveToLocalStorage(newValue);
});
},
],
});
以下、解説となります。
if (typeof window === "undefined") {
return "";
}
window オブジェクトの未定義エラー回避のため、関数式 getToLocalStorage
と関数式 saveToLocalStorage
内で typeof window === 'undefined'
を条件としてif文を定義しています。
const getToLocalStorage = () => {
if (typeof window === "undefined") {
return "";
}
const value = window.localStorage
.getItem(LOCAL_STORAGE_KEY);
return value ? JSON.parse(value) : "";
};
Local Storage から値を取得するための関数式です。
Local Storage に値がない場合、空の文字列を返します。
(※今回は値の型は String
とします。)
const saveToLocalStorage = (value: string) => {
if (typeof window === "undefined") {
return;
}
window.localStorage
.setItem(LOCAL_STORAGE_KEY, JSON.stringify(value));
};
引数として渡された値を Local Storage にセットする関数式です。
export const recoilWithLocalStorage = atom<string>({
key: "recoilWithLocalStorage",
default: getToLocalStorage(),
effects_UNSTABLE: [
({ onSet }) => {
onSet((newValue) => {
saveToLocalStorage(newValue);
});
},
],
});
Recoil の atom
を定義します。
デフォルトの値として、`getToLocalStorage` から取得した値を default
として設定します。
`effects_UNSTABLE` に新しい値がセットされたタイミングで saveToLocalStorage
に新しい値を渡す処理を設定することで、Recoil のデータストア側の値と Local Storage の値を同時に更新して、実質的にデータを共有しているような実装が可能となります。
使い方
import React from "react";
import { useRecoilState } from "recoil";
export const MyComponent = () => {
const [value, setValue] = useRecoilState(recoilWithLocalStorage);
};
useRecoilState
や useRecoilValue
などの Recoil が提供しているカスタムフックの引数に定義したストアを渡すことで、`RecoilRoot`内であればどこのコンポーネントからでもステートの呼び出しやセットが可能となります。
終わりに
株式会社イチマルイチデザインでは、私たちと一緒に React・Next.js、TypeScript などの技術を使った WEB アプリケーションや WEB サイトの開発をするフロントエンドエンジニアの仲間を募集しています。
デザイナーやバックエンドエンジニアの方も募集をしておりますので、興味がある方はご連絡お待ちしております。
関連記事
Category