React conf 2021 の気になったテーマをまとめてみた(Suspense / Automatic batching / React without memo )


12/9 に React conf 2021 が開催されました！！

https://www.youtube.com/channel/UC1hOCRBN2mnXgN5reSoO3pQ




## React Suspense
やはり React 18 のメインコンテンツは`Suspense`ですよね。
ついに`Suspense`が使えるようになります...！！

### React Suspenseとは？
今まで、非同期APIでデータフェッチした時に、下記のようなコードを書いたことはありませんか？

```jsx
export const List = () => {
  const [items, isLoading] = useData(...);

  if (isLoading) return <Loading />;

  return items.map(item => (
    <li>{item.something}</li>
  ));
}
```

このコンポーネントでは、下記のようなことを行っています。

* データを取得する
* データがロード状態である時、Loadingコンポーネントの表示
* 取得したデータの表示

しかし、下記2つは同じ場所にいる必要がありません。

* データの取得
* ローディング状態の処理

理由は下記のように述べられています。

* データフェッチする時に、常にロード状態を返却する必要がある
* 任意のコンポーネント内でデータを追加/削除などの変更があった際に、その度にローディング状態をどうするか考えなくてはいけない
    * ローディング状態どうするか問題がデータに紐付きすぎている

これらを解決するのが`Suspense`です。

```jsx
// 子コンポーネント(<List />)の準備ができているか検知し、できていなかったら<Loading />を表示する
export const Page = () => {
  return (
    <Suspense fallback={<Loading />} >
      <List />
    </Suspense>
  )
}

// ここでローディングなのかを知る必要がない
export const List = () => {
  const [item] = useData(...);

  return items.map(item => (
    <li>{item.something}</li>
  ));
}
```

もし、<Suspense>の`children`が準備できていなかった場合、fallbackに定義されたコンポーネントが表示されます。
つまり、`Suspense`では、「データが準備されたか」ではなく「JSXが準備されたか」という考え方に変わったのです。

そのため、データの依存関係やコンポーネントの依存関係を考えず、スケルトンやスピナーなどの準備状態のUIを表示することができるのです。


▼ 参考

https://www.youtube.com/watch?v=FZ0cG47msEk

## Automatic batching
今まで下記のようにset関数を３つ書いた場合、3回再レンダーが走りました。

```jsx
const handleClick = () => {
  setIsFetching(false)
  setError(null)
  setFormStatus('success')
}
```

しかし、set関数を呼ばれる度にレンダリングするのではなく
**関数の最後**のみ実行されるようになります。
つまり、`handleClick`は1回のみのレンダリングで済むようになります！


▼ 参考

https://www.youtube.com/watch?v=ytudH8je5ko

## React without memo
React Forgetという研究プロジェクションによる発表です。
これはまだ進行中のプロジェクトであり、まだリリースされていないものになります。

そもそもメモ化とはなんぞ？という人は、下記記事を参考にしてください。(告知)

https://qiita.com/cheez921/items/bb2ea0593c44300d0b32


メモ化することで、不要な再レンダリングを減らすことができるためユーザーには良い体験を与えられます。
一方で、データの依存関係や参照の同一性を考えてメモ化しなきゃいけないため、開発者は考えることが多い上にコード量も増えていきます。

UXとDX...この両方がよい状態にするにはどうすれば良いでしょう。
そこで、メモ化の方法を再検討したそうです。

### 大前提
`useMemo`や`useCallback`は、`props`や`state`の入力を受け取って、
UIやエフェクトなどに出力するための関数に過ぎません。

### useMemoの再検討
```js
const filtered = useMemo(
  () => getFiltered(todos, visibility),
  [todos, visibility]
)
```

useMemoがしていることは、キャッシュされている前回のレンダリングの値と比較して、
値に変更があったら再実行、値に変更がなかったらそのままにしているだけです。

```js
let hasVisibilityChanged, hasTodosChanged, memoCache;

let filtered;
if (hasVisibilityChanged || hasTodosChanged) {
  filtered = memoCache[1] = getFiltered(todos, visibility)
} else {
  filtered = memoCache[1]
}

```

### useCallbackの再検討
```js
const handleChange = useCallback(
  todo => setTodos((todos) => getUpdated(todos, todo)),
  []
)
```
useCallbackにおいても、前回の値がなかったら生成してキャッシュさせてあげるだけです。

```js
const handleChange =
  memoCache[0] ||
  (memoCache[0] = (todo) => setTodos((todos) => getUpdated(todos, todo)));
```

このような仕組みを用いて、関数や値、さらには`jsx`などを自動的にメモライズしてくれる仕込みを
未来のReactに導入するみたいです！！ :heart_eyes: :heart_eyes: :heart_eyes:

すでにでdemoがあります。

▼ demo映像からのリンク

https://youtu.be/lGEMwh32soc?t=501


期待大ですね！！この研究がうまくいくことを願っています。

---

これらはReact Confのほんの一部でしかありません！！
こちらに全動画がまとまっているので、ぜひチェックしてみてください:qiitan:

https://www.youtube.com/channel/UC1hOCRBN2mnXgN5reSoO3pQ/videos