【React】Zustandで、簡単に状態管理する
React

【React】Zustandで、簡単に状態管理する

作成日:2023年01月09日
更新日:2023年01月09日

今回は、Zustand(ツースタンド)という、React で状態管理するためのライブラリを紹介します。

Zustand は、かなり軽量なアプリで、かつグローバルな状態で簡単に管理することができます。

前提条件

今回テストするために、react-router-dom(v6.6.1)をインストールしています。

App.tsx

tsx
import React from "react";
import "./App.css";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import Test1 from "./Test1";
import Test2 from "./Test2";
function App() {
const router = createBrowserRouter([
{
path: "/",
element: <Test1 />,
},
{
path: "/test2",
element: <Test2 />,
},
]);
return (
<div className="App">
<RouterProvider router={router} />
</div>
);
}
export default App;

インストールする

まずは、Zustand をインストールします。

ターミナルで、npm install --save zustandを実行しましょう。

フックを作成する

Zustand のインストールが完了したので、フックを作成します。

今回は、簡単にカウントアップを行います。

hooks フォルダに countStore.ts を作成します。

zustand からcreateをインポートします。

tsx
import create from "zustand";

useCountStoreを作成し、create内でアロー関数を作成します。

初期値のcountsは 0 にし、increaseが動作するたびにcountsが 1 増えるようにします。

setで React のuseStateのように、状態を更新します。

tsx
import create from "zustand";
interface CountState {
counts: number;
increase: () => void;
}
export const useCountStore = create<CountState>((set) => ({
counts: 0,
increase: () => set((state) => ({ counts: state.counts + 1 })),
}));

フックが完成したので、Test1 ページで使用します。

状態管理する

まずは、ブラウザに初期値を表示します。

Test1 ページでuseCountStoreをインポートします。

useCountStoreの中で、countsを指定します。

tsx
import React from "react";
import { useCountStore } from "./hooks/countStore";
function Test1() {
const counts = useCountStore((state) => state.counts);
return (
<>
<h1>Test1ページ</h1>
<h2>{counts}</h2>
</>
);
}
export default Test1;

ブラウザで確認すると、

image2

countsの初期値である 0 を表示することができました。

次に、increaseを追加します。

countsの下に、increaseを作成しましょう。

tsx
function Test1() {
const counts = useCountStore((state) => state.counts);
const increase = useCountStore((state) => state.increase);

『+』ボタンを作成します。

tsx
<>
<h1>Test1ページ</h1>
<h2>{counts}</h2>
<button onClick={increase}>+</button>
</>

ブラウザを確認しましょう。

image3

『+』ボタンをクリックすると、

image4

カウントが増えていきました。

また、zustand のshallowを使うことで、同じフックを一つにまとめることができます。

tsx
import React from "react";
import shallow from "zustand/shallow";
import { useCountStore } from "./hooks/countStore";
function Test1() {
const { counts, increase } = useCountStore(
(state) => ({ counts: state.counts, increase: state.increase }),
shallow
);

次に、React Router を使って、Test2 ページへ画面遷移するようにします。

Test1.tsx を作成します。

Test2.tsx

tsx
import React from "react";
import { useCountStore } from "./hooks/countStore";
function Test2() {
const counts = useCountStore((state) => state.counts);
return (
<>
<h1>Test2ページ</h1>
<h2 style={{ fontSize: "48px" }}>{counts}</h2>
</>
);
}
export default Test2;

Test1 ページにreact-router-domをインポートします。

Test2 ページへ遷移するリンクを作成します。

tsx
import React from "react";
import shallow from "zustand/shallow";
import { Link } from "react-router-dom";
import { useCountStore } from "./hooks/countStore";
function Test1() {
const { counts, increase } = useCountStore(
(state) => ({ counts: state.counts, increase: state.increase }),
shallow
);
return (
<>
<h1>Test1ページ</h1>
<h2>{counts}</h2>
<button onClick={increase}>+</button>
<div style={{ marginTop: "2rem" }}>
<Link to={"/test2"}>Test2ページへ</Link>
</div>
</>
);
}
export default Test1;

では、ブラウザで状態管理できているか確認します。

image5

Test2 ページへ遷移すると、

image6

counts が 6 の状態のまま、Test2 ページへ遷移しました。

© 2024あずきぱんウェブスタジオ