HOCとは
高階コンポーネントは、コンポーネントロジックを再利用するためのReactの高度なテクノロジーです!Reactの機能の一部ではなく、Reactの構成的な特性から出るパターンです。
具体的には、高階コンポーネントはコンポーネントを取得し、新しいコンポーネントを返す関数です。
パラメータでコンポーネントを受け取り、リターン値で新しいコンポーネントをリターンします。
これにより共通した機能を具現し、再利用する。
簡単な例
以下は、3秒間ローディングしてからコンポーネントがロードされるロジックです。
ロジックからわかる共通的な部分は
①3秒間ローディング
②ローディングが完了したらコンポーネントがロードされる
になります。これらをHOCを使って、共通的な部分は再利用できるように抜き出すことができます。
import React, { useState } from 'react'
import { useEffect } from 'react';
export default function Button() {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(
() => setLoading(false)
, 3000);
return () => clearInterval(timer);
})
return loading ? <p>Loading...</p> : <button>Button</button>;
}
import React, { useState } from 'react'
import { useEffect } from 'react';
export default function Input() {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(
() => setLoading(false)
, 3000);
return () => clearInterval(timer);
})
return loading ? <p>Loading...</p> : <input defaultValue={"Input"} />;
}
!以下からはHOCを導入した例!
import React, { useState } from 'react'
import { useEffect } from 'react';
import withLoading from './withLoading';
function Button() {
return <button>Button</button>
}
export default withLoading(Button); // HOCからcomponentをリターンしてもらう
import React, { useState } from 'react'
import { useEffect } from 'react';
import withLoading from './withLoading';
export default function Input() {
return <input defaultValue={"Input"} />;
}
export default withLoading(Input); // HOCからcomponentをリターンしてもらう
ButtonコンポーネントとInputコンポーネントで、共通のロジックは全部省かれました。
その代わりに、最後にHOCを呼び出すロジックが追加されました。
最初に話した通りに、HOCはパラメータとしてコンポーネントを渡してリターン値がコンポーネントでありため、
export default {HOCコンポーネント(コンポーネント)} と記載しています。
import React, { useState } from 'react'
import { useEffect } from 'react';
export default function withLoading(Compomnent) {
const WithLoadingComponent = (props) => {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(
() => setLoading(false)
, 3000);
return () => clearInterval(timer);
})
return loading ? <p>Loading...</p> : <Compomnent {...props}/>;
}
return WithLoadngComponent;
}
上は、HOCです。ロジックからも分かるように、高階コンポーネントは、パラメータとして受け取ったコンポーネントを修正しません。
受け取ったコンポーネントで梱包して、受け取ったのコンポーネントの各各のpropsにてレンダリングすることができます。
そして、高階コンポーネントはSide Effectのない純粋関数でもあリます(withLoadingが小文字で始まる理由!)。純粋関数の中でComponentを作成し、そのままリターンする構造を持っています。
HOC命名ルールはwith〜〜になります。