React: コンポーネントのロジックをカスタムフックに切り出す ー カウンターの作例で
Reactにフックが採り入れられて、関数コンポーネントに状態をもたせられるようになりました。
「フックとは、関数コンポーネントにstateやライフサイクルといった Reactの機能を「接続する」(hook into)ための関数です」(「要するにフックとは?」)。さらに、フックを独自につくって、コンポーネントからロジックを切り出すこともできます。そうすれば、コンポーネントのコードがすっきり見やすくなるとともに、そのカスタムフックを使い回すこともできるのです。
自分独自のフックを作成することで、コンポーネントからロジックを抽出して再利用可能な関数を作ることが可能です。
(「独自フックの作成」より)
本稿は簡単なカウンターの作例をとおして、フックの役割や考え方について解説します。
Create React Appでアプリケーションのひな形をつくる
まず、Reactアプリケーションのひな形は、Create React Appでつくりましょう。コマンドラインツールでnpx create-react-app
につづけて、アプリケーション名(今回はreact-custom-hook
)を打ち込んでください。
npx create-react-app react-custom-hook
アプリケーション名でつくられたディレクトリに切り替えて(cd react-custom-hook
)、コマンドyarn start
でひな形アプリケーションのページがローカルホスト(http://localhost:3000/
)で開くはずです。
useState
とプロパティ(props
)でカウンターをつくる
まずは、カスタムフックは用いず、useState
とプロパティ(props
)によりカウンターをつくりました(コード001)。
アプリケーションのモジュールsrc/App.js
にuseState
で状態変数(count
)を定め、関数としてはカウンターの減算(decrement()
)と加算(increment()
)が備わっています。それらをプロパティ(counter
)として受け取るのが、このあと定めるカウンター表示のコンポーネントCounterDisplay
です。
コード001■useState
とプロパティを用いたアプリケーションモジュール
import React, { useState } from 'react';
import CounterDisplay from './CounterDisplay';
import './App.css';
const initialCount = 0;
function App() {
const [count, setCount] = useState(initialCount);
const decrement = () => setCount(count - 1);
const increment = () => setCount(count + 1);
return (
<div className="App">
<CounterDisplay counter={{ count, decrement, increment }} />
</div>
);
}
export default App;
カウンター表示のモジュールsrc/CounterDisplay.js
は、アプリケーションから受け取ったプロパティ(counter
)により、カウンタの値(counter.count
)表示と減算(counter.decrement
)・加算(counter.increment
)の処理を行います(コード002)。
コード002■カウンター表示のモジュール
import React from "react";
const CounterDisplay = ({ counter }) => {
return (
<div>
<button onClick={counter.decrement}>-</button>
<span>{counter.count}</span>
<button onClick={counter.increment}>+</button>
</div>
);
}
export default CounterDisplay;
これで簡単なカウンターができ上がりました(図001)。ただカウンターのカウントアップ・ダウンをするだけで、アプリケーションモジュールには、状態を使って何か行うという処理がありません。あとで加わるという想定にして、今回の作例からは省きました。また、CSS(src/index.css
とsrc/App.css
)は、基本的なフォントや余白の設定のみです。確かめたい方は、最後に掲げるCodeSandboxの作例(サンプル001)をご覧ください。
図001■でき上がったカウンター
アプリケーションのロジックをカスタムフックに切り出す
アプリケーションモジュールsrc/App.js
のロジック、つまり状態変数とその処理関数を、このあと定めるカスタムフックに切り出しましょう。
// import React, { useState } from 'react';
import React from 'react';
// const initialCount = 0;
function App() {
/* カスタムフックに切り出す
const [count, setCount] = useState(initialCount);
const decrement = () => setCount(count - 1);
const increment = () => setCount(count + 1);
*/
}
つぎのコード003が、カウンターのカスタムフックのモジュール(src/useCounter.js
)です。フックの名前はuse
ではじめるお約束になっています。状態が備えられ、フックも使えるのは、関数コンポーネントと同じです。違いとしては、JSXの要素を返さなくて構いません。戻り値は、カウンターの値(count
)と減算(decrement()
)・加算(incfrement()
)の関数を収めたオブジェクトとしました。
コード003■カウンターのカスタムフック
import { useState } from 'react';
export const useCounter = (initialCount = 0) => {
const [count, setCount] = useState(initialCount);
const decrement = () => setCount(count - 1);
const increment = () => setCount(count + 1);
return { count, decrement, increment };
};
カスタムフックを使う
カウンター表示モジュール(src/CounterDisplay.js
)はカスタムフック(useCounter
)の呼び出しにより、カウンターの状態を操作するための参照(count
とdecrement
およびincrement
)が得られます。もはや、親コンポーネントからプロパティで受け取らなくてよいのです。
import { useCounter } from "./useCounter";
// const CounterDisplay = ({ counter }) => {
const CounterDisplay = () => {
const { count, decrement, increment } = useCounter();
return (
<div>
{/* <button onClick={counter.decrement}>-</button> */}
<button onClick={decrement}>-</button>
{/* <span>{counter.count}</span> */}
<span>{count}</span>
{/* <button onClick={counter.increment}>+</button> */}
<button onClick={increment}>+</button>
</div>
);
}
親のアプリケーションモジュール(src/App.js
)から、子コンポーネント(CounterDisplay
)に渡していたプロパティ(counter
)は除いてください。
function App() {
return (
<div className="App">
{/* <CounterDisplay counter={{ count, decrement, increment }} /> */}
<CounterDisplay />
</div>
);
}
カウンター表示(src/CounterDisplay.js
)とアプリケーション(src/App.js
)モジュールの記述全体は、それぞれつぎのコード004のとおりです。ロジックを切り離したので、ふたつのコンポーネントはともに表示に専念することになりました。作例をCodeSandboxに公開します(サンプル001)。
コード004■ロジックを切り離したコンポーネントモジュール
import React from "react";
import { useCounter } from "./useCounter";
const CounterDisplay = () => {
const { count, decrement, increment } = useCounter();
return (
<div>
<button onClick={decrement}>-</button>
<span>{count}</span>
<button onClick={increment}>+</button>
</div>
);
}
export default CounterDisplay;
import React from 'react';
import CounterDisplay from './CounterDisplay';
import './App.css';
function App() {
return (
<div className="App">
<CounterDisplay />
</div>
);
}
export default App;
サンプル001■カスタムフックを使ったカウンター
Author And Source
この問題について(React: コンポーネントのロジックをカスタムフックに切り出す ー カウンターの作例で), 我々は、より多くの情報をここで見つけました https://qiita.com/FumioNonaka/items/62285e474608388cbbe3著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .