React の関数コンポーネントにはロジックをコンポーネントから分離してまとめるフックという機能があります。
独自フックの作成 – React
これは処理をフックという別ファイルにまとめてコンポーネントに書くもの処理の呼び出しと UI 本体についての記述に留めようとする整理方法です。これは例えば次の様にできます。
import React, { useState, useEffect } from 'react';
function FriendListItem(props) {
// ここから
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
// ここまでの処理を別にまとめたい
return (
<li style={{ color: isOnline ? 'green' : 'black' }}>
{props.friend.name}
</li>
);
}
/** ↑の一コンポーネントファイルを↓の二つに分割 */
// コンポーネントファイル
import React from 'react';
function FriendListItem(props) {
const isOnline = useIsOnline(props.friend.id);
return (
<li style={{ color: isOnline ? 'green' : 'black' }}>
{props.friend.name}
</li>
);
}
// フックファイル
import { useState, useEffect } from 'react';
function useIsOnline(friendId) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(friendId, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendId, handleStatusChange);
};
});
return isOnline;
}
コンポーネントファイルがすっきりしました。この様にフックに個々の処理をまとめると多様な処理をする必要な画面であっても、多様な処理を記述する必要はなく、多様な呼び出しをするのみ(useXXXを大量に書く感じです)で済みます。
このフックへの処理の抜き出しですが IDE の PhpStorm のリファクタ機能を使うことで、簡易にできます。使う機能はメソッドの抽出です。
JavaScript のリファクタリング | PhpStorm#メソッドの抽出
この機能で処理の範囲を選んでメソッドにするだけでもう、それはフックになります。外部に露出させる、引数、返り値も大体最小限になり便利です。
