17
8

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 5 years have passed since last update.

React HooksAdvent Calendar 2019

Day 2

react-hooks-global-stateの紹介

Last updated at Posted at 2019-12-01

はじめに

React Hooksがアナウンスされた時に、まずやってみようと思ったことが簡易なglobal stateの実現でした。React Hooks登場以前から試みていたのですが、それのHooks版を開発しました。

ライブラリ

https://github.com/dai-shi/react-hooks-global-state

このライブラリはとてもシンプルなものになっています。つまり、React ContextとReact Hooksを素直に使ったglobal stateになっています。

いくつかの特徴はありますが、あとで説明します。

使い方

まず必要なライブラリをimportします。

import React from 'react';
import { createGlobalState } from 'react-hooks-global-state';

最初にinitialStateを定義します。

const initialState = {
  count: 0,
  text: 'hello',
 };

次に、それをもとにglobal stateを作成します。

const { GlobalStateProvider, useGlobalState } = createGlobalState(initialState);

global stateを使うコンポーネントを作ります。

const Counter = () => {
  const [count, setCount] = useGlobalState('count');
  return (
    <div>
      <span>Counter: {count}</span>
      <button onClick={() => setCount(v => v + 1)}>+1</button>
      <button onClick={() => setCount(count - 1)}>-1</button>
    </div>
  );
};

useGlobalStateの引数にglobal stateのproperty nameを指定しているところがポイントです。これを指定することで他のpropertyが変更にあった場合でも本コンポーネントは再renderする必要がなくなります。

最後にAppでProviderを指定します。

const App = () => (
  <GlobalStateProvider>
    <Counter />
    <Counter />
  </GlobalStateProvider>
);

デモ

CodeSandboxで動作させることができます。

特徴

React ContextとReact Hooksを使ってglobal stateを実現するライブラリは世の中にたくさんあります。本ライブラリはそのうちの一つですが、いくつかの特徴があります。

select by property name

global stateを設計する上でのポイントの一つは、大きなstateのうち、一部分を使う場合にそれを限定して使うための仕組みです。例えば、Reduxではselectorというインタフェースを使って、stateから派生したデータを作ります。本ライブラリはよりシンプルな手法として、stateオブジェクトのproperty nameでselectするという手法を採用しています。これは、selectorのようにオブジェクトの深い構造をselectすることはできませんが、reselectのようなselectorをmemoizeする必要がないというメリットがあります。その代わりstateオブジェクトはflatになるような設計にする必要はあります。同様のアプローチを採用しているライブラリにstoreonがあります。

unstable_observedBits

本ライブラリは上記selectの実現にobservedBitsという仕組みを使っています。observedBitsについてはこちらの記事が詳しいです。この仕組みを使うと、contextが変更した際に、一部のコンポーネントだけを再renderすることができます。

おわりに

本ライブラリは、名前が直接的なためか比較的参照されることが多いようですが、実は今後の方針は悩んでいます。一つは、今回紹介しなかったreducerインタフェースがReduxの完全な互換にはできないことと、もう一つは、observedBitsが将来のReactでは使えなくなる可能性が高いことがあります。ユーザの利用シーンをヒアリングしつつ今後の方針を決めていきたいと思います。

17
8
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
17
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?