24
11

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.

CoconeAdvent Calendar 2022

Day 24

2022年の React/Next.js 振り返り

Last updated at Posted at 2022-12-23

:christmas_tree: Happy Merry Christmas! :christmas_tree:

今日はときめきのクリスマスイブです!
クリスマスマーケットに行って:wine_glass:ホットワイン:wine_glass:でも飲みたいですね:blush:
みなさんも楽しいクリスマスをお過ごしください!

さて、今年も残り一週間となりましたね。

今年はReact/Nextjsを使って新規開発をしていたら、
React18がリリースされたり、
Next.js13が発表されたり
新規プロジェクトでは今までと違う状態管理(Zustand)を導入してみたりして
勉強しながら、試行錯誤しながら楽しく開発出来た年でした。

その中でよかったな...と思う機能を少しご紹介したいと思います。

1. React18で追加されたパフォーマンス向上してくれる機能

React18ではいろんな機能が追加・改善されましたが、その中でパフォーマンスを向上してくれる以下の機能を紹介します。

1) レンダリングのbatch機能

今まではstateが変更する度に再レンダリングしたのが、stateが全部更新されてから再レンダリングされることが可能になりました。
image.png

2) useTransition

例えばレンダリング処理が多くて画面が重くなる時を無理やり作ってみました。

import { useState } from 'react';

// 配列10000個を作っちゃった>< <=こら!
const a = new Array(10000).fill(0)

function App() {
  const [ name, setName ] = useState('');
  return (
    <div className="App">
      // タイピングするたびに10000配列のレンダリングを行うとしたら?
      <input onChange={(e) => { setName(e.target.name) }} />
      {a.map(() => {
        return <div>{name}</div>
      }}
    </div>
  )
}

  • useTransitionを使て解決しよう
  • startTransitionで問題を起こすstateを囲む
- import { useState } from 'react';
+ import { useState, useTransition } from 'react';
const a = new Array(10000).fill(0)
function App() {
  const [ name, setName ] = useState('');
+ const [ isPending, startTransition ] = useTransition();
  return (
    <div className="App">
-     <input onChange={(e) => { setName(e.target.name) }} />
+     <input onChange={(e) => {
+       startTransition(() => {
+         setName(e.target.name) <= 問題を起こしているstate
+       })
+     }} />
-     {a.map(() => {
-       return <div>{name}</div>
-     }}
+     {
+       isPending ? <>Loading...</> :
+       a.map(() => {
+           return <div>{name}</div>
+       }
+     }
    </div>
  )
}

今の画面を残しつつ次の画面を裏でレンダリングしてくれます。素晴らしい:clap_tone2:

3) useDeferredValue

上の問題をuseDeferredValueを使って解決してみよう

- import { useState } from 'react';
+ import { useState, useDeferredValue } from 'react';
const a = new Array(10000).fill(0)
function App() {
  const [ name, setName ] = useState('');
+ const state = useDeferredValue(name) 
  return (
    <div className="App">
      <input onChange={(e) => { setName(e.target.name) }} />
      {a.map(() => {
-        return <div>{name}</div>
+        return <div>{state}</div>
      }}
    </div>
  )
}

useDeferredValueは値の変化をいい感じに延期してくれます。これも素晴らしい:clap_tone2:

2. Zustandを使ったシンプル過ぎる状態管理

いままでredux-sagaやredux-toolkitを使って状態管理を行っていたのですが、
zustandを知って調べてみたら、今までより圧倒的にシンプルで分かりやすく
これは新しいプロジェクトに使ってみたい!と思って、導入を試しました。

導入方法はとてもシンプルです。

  • storeの生成
  • storeの作成にはcreateを使う
  • createsetgetを引数に取る
  • setはstateを更新、getはstateを取得する
import create from 'zustand';

const useStore = create((set, get) => ({
  count: 1,
  addCount: () => set((state) => ({ count: state.count + 1 })),
  resetCount: () => set(() => ({ count: 1 })),

  userList: [],

  // 非同期処理もstore内部で簡単に書ける
  fetchUserList: async () => {
    const res = await fetchData();

    // getでstateを取得
    set({ data: get().userList.concat(res.data) });
  },
}))

export default function Counter() {
  const { count, addCount, resetCount } = useStore();
  return (
    <div className="counter">
      <span>{count}</span>
      <button onClick={addCount}>+1</button>
    </div>
  );
}

複数のstoreを生成&利用ももちろん可能です。

const useAuthStore = create((set, get) => ({ ... });
const useCountStore = create((set, get) => ({ ... });
export default function App() {
  const { authInfo } = useAuthStore();
  const { count, addCount } = useCountStore();
  return (
    <div className="main">
      ...
    </div>
  );
}

今のところ無難に開発出来て、学習コストも低くて、コードもシンプルになるので、しばらくは愛用しそうです。
みなさんも是非使ってみてください。

まとめ

最初Reactを触れた時はわからないことが多かったですが、どんどん機能も追加&改善され、開発が楽しくなりました。
さらに10月に発表されたNext.js13では新しいバンドルツール(Turbopack)や新しいRouting Systemなど、大きな進化があるようで(この内容に関しては別の記事で触れたいと思います)まだまだ楽しみが続きそうですね。

この勢いで年末年始休みにはReactやFlutterを使って何かアプリを開発したいと思ったりしてます。
では、今年も残りわずかですが、有意義な時間をお過ごしください。

24
11
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
24
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?