29
32

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.

Recoilを基礎から理解しよう!(環境構築・Atom編)

Last updated at Posted at 2022-02-20

この記事は

  • Reactで状態管理ツールを使ってみたい。
  • でも学習コストが高くて難しそう。

そのように感じている人向けに、Recoilの使い方をまとめたものになっています。

筆者はReduxという類似ツールを使ったことがありますが、「圧倒的にRecoilは簡単」 だと思っています!
状態管理ツールの選定に迷っている人、Recoilの利用を考えてみてはいかがでしょうか!!

Recoilってなに?

Reactの提供元であるMeta(FaceBook)が開発中の新しい状態管理ライブラリです。
ReduxやReactQueryの立ち位置のライブラリになります!

2022年2月時点ではプレリリース状態(v0.6.1)となっていますが、作っているのがReactの生みの親ですので状態管理ライブラリとして標準利用される可能性大だと思っています。

実装

それでは早速書いていきましょう!

まず初めに

Next.jsやRecoilなど必要なライブラリをインストールします。

まず最初にNext.jsのインストール。

npx create-next-app nextjs-recoil

作成されたnextjs-recoilディレクトリの中身をルートディレクトリに持ってきます。
(ちょっと見栄えが悪いので..)

こんな感じに移動させてください!

.
├── LICENSE
├── README copy.md
├── README.md
├── next.config.js
├── node_modules
├── package-lock.json
├── package.json
├── pages
├── public
└── styles

今回のメインのRecoilをインストールします。

npm install --save recoil

Recoilを有効化

RecoilはRecoilRootで囲ったコンポーネント内で利用できます。
公式ではルートコンポーネントに配置するのを推奨しているようですので/pages/_app.jsに配置しましょう。

/pages/_app.js
import { RecoilRoot } from 'recoil';

function MyApp({ Component, pageProps }) {
  return (
    <RecoilRoot>
      <Component {...pageProps} />
    </RecoilRoot>
  )
}

export default MyApp

これだけの設定でRecoilを利用できるようになります!
(めちゃめちゃ簡単ですね...!)

Next.jsを起動させましょう。

npm run dev

Atomって何?

RecoilではAtomという単位で、各状態の管理を行うことができます。
以下のようなAtomを作成することで、異なるページ間の状態管理をすることができます。

Atomの基本形

const todoState = atom({
  key: "todo", // 一位のキー名
  default: ["todo1"], // 初期値
});
  • key: 作成したAtomに付与する一位のキー名(重複不可)
  • default: Atomの初期値

データを表示・更新させる

今回は簡単なTodoアプリを作成するので、Todoの状態を管理するAtomを作成します。
/recoil/todo.jsAtomを作成し、どのディレクトリでも利用できるようexportしておきましょう。

/recoil/todo.js
import { atom } from "recoil";

//todo Atom
export const todoState = atom({
  key: "todo",
  default: ["todo1"]
});

先ほど作成したAtomを早速表示させましょう。
Recoilは基本的にReactHooksを用いて状態の操作を行います。
データを編集する場合は、useRecoilState()を利用します。

useRecoilState()の基本形

//const [Atomの状態変数, Atomを更新する関数] = useRecoilState(対象のAtom)
const [todoList, setTodoList] = useRecoilState(todoState)
  • 1つ目の要素: Atomの現在の値
  • 2つ目の要素: Atomの現在の値を更新するための関数

今回はこのような形で/pages/index.jsに実装します。

/pages/index.js
import { useState } from "react"
import { useRecoilState } from "recoil";
import { todoState } from "../recoil/todo"

export default function Home() {
  // TodoのAtomを呼び出し
  const [todoList, setTodoList] = useRecoilState(todoState)

  const [todo, setTodo] = useState("")

  const handleChange = (e) =>{
    setTodo(e.target.value)
  }

  // Todoリストを更新する
  const pushTodo = (newTodo) => {
    setTodoList([...todoList, newTodo])
    setTodo("")
  }

  return (
    <div>
      <p>todo list</p>
      <ul>
        {todoList.length && todoList.map((v, i) => (
          <li key={i}>{v}</li>
        ))}
      </ul>
      <div>
        <input type="text" value={todo} onChange={handleChange} />
        <button onClick={() => pushTodo(todo)}>
          add Todo
        </button>
      </div>
    </div>
  )
}

localhost:3000 にアクセスするとTodoアプリができていると思います!

gif1.gif

[Tips]
RecoilにはuseRecoilValue()というデータ表示のみ行うHooksと、useSetRecoilState()という状態の更新のみを行うHooksも用意されています。
useRecoilValue()はあまり使わないかもですが、useSetRecoilState()は是非活用して欲しいです!
Reactのパフォーマンス向上には、データの再レンダリングを少なくすることが重要になります。
useSetRecoilState()を利用することで、不要なレンダリング防止に繋がります。
状態の更新のみを行う場合は、積極的に使っていきましょう!!

// Todo Atomのデータ表示のみを行う場合、こんな感じ
const todoList = useRecoilValue(todoState)
// Todo Atomのデータ更新のみを行う場合、こんな感じ
const setTodoList = useSetRecoilState(todoState)

最後に

次回はRecoilのSelectorについて書きたいと思います!

今回利用したコードはこちらになります!(不要なファイルは削除してあります。)
https://github.com/takusan64/nextjs-recoil

29
32
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
29
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?