LoginSignup
3
0

【React状態管理7】valtio

Last updated at Posted at 2023-09-02

概要

React の状態管理の 1 つである、Valtio(ヴァルシオ)について学んだことをメモします。

学習内容

Valtio とは

Zustand や Jotai と同じ会社が作っているライブラリ。初心者向けで使いやすい。
コンポーネント側で状態を設定し、全体に渡す。
valtio は React 外で動く。

特長

  • Proxy によりクライアントの複雑性を吸収するため、破壊的メソッドのようなことを考える必要がない
  • 記述量が少なく、簡単に使える
  • レンダリングの最適化も自動で行われる

導入方法

インストール方法

$ yarn add valtio

設定方法

  1. proxyにより、管理したいデータをstoreに保存する
export const store = proxy({ todos: [] });
  1. useSnapshotを用いて、storeで管理するデータを呼び出す。
const { todos } = useSnapshot(store);

使用例

state/todos.ts
import { Todo } from "src/types";
import { proxy } from "valtio";

// データtodosをstoreで管理する
export const store = proxy<{todos: Todo[]}>({ todos: [
    { id: 1, text: "foo", isDone: false },
    { id: 2, text: "bar", isDone: true },
    ]
});

// store内のデータtodosの要素isDoneを更新する
export const toggleIsDone = (id: Todo["id"]) => {
    store.todos.forEach((todo) => {
        todo.isDone = todo.id == id ? !todo.isDone : todo.isDone;
    });
};

// store内のデータtodosに新規のtodoを追加する
export const addTodo = (text: Todo["text"]) => {
    store.todos.push({id: store.todos.length + 1, text, isDone: false});
}
pages/index.tsx
import type { NextPage } from "next";
import { store, toggleIsDone } from "src/state/todo";
import { useSnapshot } from "valtio";

const Home: NextPage = () => {
  const { todos } = useSnapshot(store); // storeのデータtodosを取得する

  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)} // storeのデータtodos内の値を更新する
              style={{ width: "1.5rem", height: "1.5rem" }}
            />
            {todo.text}
          </label>
        </div>
      ))}
    </div>
  );
};

export default Home;
pages/add.tsx
import type { NextPage } from "next";
import { ComponentProps } from "react";
import { addTodo } from "src/state/todo";

const Add: NextPage = () => {
  const handleSubmit: ComponentProps<"form">["onSubmit"] = (e) => {
    e.preventDefault();
    addTodo(e.currentTarget.text.value); // storeのデータtodosに新規の値を追加する
    e.currentTarget.reset();
  };

  return (
    <div>
      <h3>TODO追加</h3>
      <form onSubmit={handleSubmit}>
        <input type="text" name="text" autoComplete="off" required />
        <button>追加</button>
      </form>
    </div>
  );
};

export default Add;

参考

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

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