はじめに
多くの方が既にuseContextやuseReducerを使い、Reduxのようなprops-drillingを回避するようなHooksを作っています。そこで今回はreact-trackedを使いReduxが解決した機能の一つであるpropsdrilling回避を実現したいと思います。
react-trackedの利点については@daishiさんのreact-trackedの紹介という記事をご参照ください。
react-trackedを使ってみる
今回はカウンターアプリを作っていきたいと思います。
ファイル構成
今回のファイル構成は以下です。store.jsにglobalに置きたい変数、reducerを置きます。
src
|-- index.js
|-- App.js
|-- store.js
|-- Components
|-- Counter.js
|-- Display.js
store.jsに初期値を設定&Reducerを置き、Providerを定義する
今回はカウンターアプリなので、以下のように設定します。
import { useReducer } from "react";
import { createContainer } from "react-tracked";
const initialState = { count: 0 };
const reducer = (state, action) => {
switch (action.type) {
case "INCREMENT_COUNT":
return { ...state, count: state.count + 1 };
case "DECREMENT_COUNT":
return { ...state, count: state.count - 1 };
default:
throw new Error();
}
};
const useValue = () => useReducer(reducer, initialState);
export const {
Provider,
useTrackedState,
useUpdate: useDispatch
} = createContainer(useValue);
ProviderをApp.jsに適用し、変数、reducerにアクセスできるようにする
Providerでコンポーネント全体をラップします。各コンポーネントに関しては下で説明します。
import React from "react";
import Display from "./Components/Display";
import Counter from "./Components/Counter";
import { Provider } from "./store";
const App = () => {
return (
<Provider>
<Display />
<hr />
<Counter />
</Provider>
);
};
export default App;
Count機能を作るCounterコンポーネントとCountの値表示機能を作るDisplayコンポーネントを作成。
今回の作ったコンポーネントはComponentsディレクトリにまとめておきます。
まずはCount機能
import React from "react";
import { useDispatch } from "../store";
const Counter = () => {
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch({ type: "INCREMENT_COUNT" })}>
Plus
</button>
<button onClick={() => dispatch({ type: "DECREMENT_COUNT" })}>
Minus
</button>
</div>
);
};
export default Counter;
次に値表示機能
import React from "react";
import { useTrackedState } from "../store";
const Display = () => {
const state = useTrackedState();
return <div>count : {state.count}</div>;
};
export default Display;
完成品
完成品についてはこのCodeSandboxのリンクから見ることができるので、動作を確認してみてください。
最後に
カウンターアプリだと結構簡単に作ることができましたが、正直これだけだとreact-truckedの「不要なrenderがパフォーマンス低下を引き起こすのを防ぐ」という面は紹介できなかったかなと思います。
詳細については上で紹介した@daishiさんのreact-trackedの紹介という記事やreact-trackedのチュートリアルを見るとよくわかると思います。
参考文献
今回カウンターアプリを作るにあたり以下の記事を参考にさせていただきました。ありがとうございました。