LoginSignup
0
0

More than 1 year has passed since last update.

HOC(Higher Order Component)を簡単な例としてやってみる

Last updated at Posted at 2023-01-30

HOCとは

高階コンポーネントは、コンポーネントロジックを再利用するためのReactの高度なテクノロジーです!
Reactの機能の一部ではなく、Reactの構成的な特性から出るパターンです。
具体的には、高階コンポーネントはコンポーネントを取得し、新しいコンポーネントを返す関数です。
パラメータでコンポーネントを受け取り、リターン値で新しいコンポーネントをリターンします。
これにより共通した機能を具現し、再利用する。

簡単な例

以下は、3秒間ローディングしてからコンポーネントがロードされるロジックです。
ロジックからわかる共通的な部分は
①3秒間ローディング
②ローディングが完了したらコンポーネントがロードされる
になります。これらをHOCを使って、共通的な部分は再利用できるように抜き出すことができます。

(HOCなし)button.jsx
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>;
}
(HOCなし)Input.jsx
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"} />;
}

image.png
 ↓
image.png

!以下からはHOCを導入した例!

(HOCあり)button.jsx
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をリターンしてもらう
(HOCあり)Input.jsx
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コンポーネント(コンポーネント)} と記載しています。

(HOC)withLoading.jsx
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〜〜になります。

0
0
1

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
0
0