5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【React状態管理6】Jotai

Posted at

概要

React の状態管理の 1 つである、Jotaiについて学んだことをメモします。

学習内容

Jotai とは

Atom ベースの状態管理。recoil の影響が強い(概念はほぼ同じ)。
ボトムアップアプローチ(コンポーネントから状態を生成する)
jotai
^1

特長

  • 簡素な記述で使える
  • 最小限のコア API (2kb)
  • 多くのユーティリティと統合
  • TypeScript 指向
  • Next.js、Gatsby、Remix、React Native で動作
  • SWC および Babel プラグインを使用した React Fast Refresh

導入方法

インストール方法

$ npm i jotai

or

$ yarn add jotai

設定方法

  1. atom()でデータを状態管理する
export const todosAtom = atom();
  1. useAtom()により、ページやコンポーネント内で状態管理しているデータを利用
const [_, setTodos] = useAtom(todosAtom);

使用例

import { atom } from "jotai";
import { Todo } from "src/types";

export const todosAtom = atom<Todo[]>([
    { id: 1, text: "foo", isDone: false },
    { id: 2, text: "bar", isDone: true },
])
import type { NextPage } from "next";
import { todosAtom } from "src/state/todo";
import { Todo } from "src/types";
import { useAtom } from "jotai";

const Home: NextPage = () => {
  const [todos, setTodos] = useAtom(todosAtom);

  const toggleIsDone = (id: Todo["id"]) => {
    setTodos((prevTodos) => {
      return prevTodos.map((todo) => {
        if (todo.id === id) {
          return { ...todo, isDone: !todo.isDone };
        }
        return todo;
      });
    });
  };

  return (
    <div>
      <h2>TODO一覧</h2>
      {todos.map((todo) => (
        <div key={todo.id}>
          <label style={{ fontSize: "2rem" }}>
            <input
              type="checkbox"
              checked={todo.isDone}
              onChange={() => toggleIsDone(todo.id)}
              style={{ width: "1.5rem", height: "1.5rem" }}
            />
            {todo.text}
          </label>
        </div>
      ))}
    </div>
  );
};

export default Home;

Selector の利用

Recoil と同様に、Jotai の Selector である、selectAtomを使うことで、簡易でかつよりパフォーマンスの高い記述ができる。

  1. selectAtomでデータの必要な要素のみを状態管理する
export const todosLenthAtom = selectAtom(todosAtom, (todos) => todos.length);
  1. useAtomにより、ページ内やコンポーネント内で必要な要素のみを状態管理から取得する
const [todosLength] = useAtom(todosLenthAtom);

使用例

データtodosのサイズ[todos.length]だけが必要な場合

import { atom } from "jotai";
import { selectAtom } from "jotai/utils";
import { Todo } from "src/types";

export const todosAtom = atom<Todo[]>([
    { id: 1, text: "foo", isDone: false },
    { id: 2, text: "bar", isDone: true },
])

export const todosLenthAtom = selectAtom(todosAtom, todos => todos.length);
import { FC } from "react";
import { todosLenthAtom } from "src/state/todo";
import { useAtom } from "jotai";

export const TodoCounter: FC = () => {
  const [todosLength] = useAtom(todosLenthAtom);
  return <h2>TODO: {todosLength}</h2>;
};

ロジックの Jotai 管理

ロジックを状態管理することで、ページやコンポーネントの記述をよりシンプルにできる。

## 使用例

import { atom } from "jotai";
import { selectAtom } from "jotai/utils";
import { Todo } from "src/types";

export const todosAtom = atom<Todo[]>([
  { id: 1, text: "foo", isDone: false },
  { id: 2, text: "bar", isDone: true },
]);

export const toggleTodoAtom = atom<Todo[], Pick<Todo, "id">>(
  (get) => get(todosAtom),
  (get, set, update) => {
    const prevTodos = get(todosAtom);
    const newTodos = prevTodos.map((todo) => {
      if (todo.id === update.id) {
        return { ...todo, isDone: !todo.isDone };
      }
      return todo;
    });
    set(todosAtom, newTodos);
  }
);
import type { NextPage } from "next";
import { toggleTodoAtom } from "src/state/todo";
import { useAtom } from "jotai";

const Home: NextPage = () => {
  const [todos, toggleTodos] = useAtom(toggleTodoAtom);

  return (
    <div>
      <h2>TODO一覧</h2>
      {todos.map((todo) => (
        <div key={todo.id}>
          <label style={{ fontSize: "2rem" }}>
            <input
              type="checkbox"
              checked={todo.isDone}
              onChange={() => toggleTodos({ id: todo.id })}
              style={{ width: "1.5rem", height: "1.5rem" }}
            />
            {todo.text}
          </label>
        </div>
      ))}
    </div>
  );
};

export default Home;

参考

IT Kingdom
Jotai 公式ページ
GitHub リポジトリ

5
2
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
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?