Reactは、モダンなウェブアプリケーション開発において非常に人気のあるライブラリであり、効率的で再利用可能なコンポーネント設計を可能にします。その中でも、高階コンポーネント(Higher-Order Components, HOC)は、特定の機能を複数のコンポーネントに簡単に適用できる便利な手法として注目されています。HOCを活用することで、重複するコードを削減し、柔軟かつスケーラブルなアプリケーション設計を実現できます。
本記事では、HOCの基本的な概念から具体的な実装例、応用的な使い方までを詳しく解説し、Reactプロジェクトでの再利用性向上を図る方法を学びます。特に、複雑なアプリケーションにおける認証やデータ管理といったシナリオにおいて、HOCがどのように役立つかを実例を交えて説明します。Reactの開発スキルを一段と高めたい方に最適なガイドです。
高階コンポーネント(HOC)とは
高階コンポーネント(Higher-Order Component, HOC)は、Reactでコンポーネントのロジックを再利用するための設計パターンです。具体的には、1つのコンポーネントを引数として受け取り、新しいコンポーネントを返す関数として定義されます。この設計により、複数のコンポーネント間でロジックを共有することが容易になります。
HOCの役割
HOCの主な役割は、次のとおりです。
- ロジックの再利用:共通の機能(例:認証、データ取得、ローディング状態の管理など)を複数のコンポーネントで簡単に共有できます。
- 関心の分離:UI(見た目)とロジックを分離し、コードの可読性と保守性を向上させます。
HOCの動作イメージ
HOCの基本的な構造は以下のようになります。
const withExampleFeature = (WrappedComponent) => {
return (props) => {
// 追加のロジックをここに記述
return <WrappedComponent {...props} />;
};
};
このwithExampleFeature
関数は、受け取ったWrappedComponent
をラップし、新しいコンポーネントを生成します。ラップされたコンポーネントには、HOCで追加されたロジックとオリジナルのPropsが適用されます。
ReactでのHOCの例
以下は、単純なHOCの例です。このHOCは、コンポーネントに現在の日時を表示する機能を追加します。
const withCurrentTime = (WrappedComponent) => {
return (props) => {
const currentTime = new Date().toLocaleTimeString();
return <WrappedComponent {...props} currentTime={currentTime} />;
};
};
const MyComponent = ({ currentTime }) => (
<div>現在の時刻: {currentTime}</div>
);
const EnhancedComponent = withCurrentTime(MyComponent);
EnhancedComponent
をレンダリングすると、元のMyComponent
に加えて、現在の時刻が表示されるようになります。このように、HOCを使うことで、元のコンポーネントに変更を加えることなく、機能を簡単に拡張できます。
再利用性の重要性
再利用性は、ソフトウェア開発全般において重要な原則ですが、特にReactのようなコンポーネント指向のライブラリでは、プロジェクトのスケーラビリティやメンテナンス性に直結します。再利用可能なコードを設計することで、開発効率の向上やエラーの削減が期待できます。
Reactにおける再利用性のメリット
- 開発時間の短縮
同じロジックやUIを複数箇所で使用する場合、共通化されたコンポーネントを使えば、新たに記述するコード量を大幅に削減できます。 - 保守性の向上
再利用可能なコンポーネントは一箇所で修正が済むため、変更が必要になった場合でも影響範囲を最小限に抑えられます。 - コードの一貫性
アプリケーション全体で一貫性のあるロジックやUIを保つことができ、ユーザー体験を向上させます。
HOCによる再利用性向上の具体例
Reactでは、以下のような機能を高階コンポーネント(HOC)として再利用することが一般的です。
- 認証ロジックの共通化
ユーザー認証を必要とする複数のページコンポーネントに共通の認証ロジックを適用します。 - データフェッチの管理
外部APIからのデータ取得を扱うロジックを分離し、複数のコンポーネントで活用可能にします。 - ローディングインジケータの追加
非同期処理中に「読み込み中」の表示を簡単に実装できます。
HOCによる効率的なプロジェクト運営
再利用可能なコードを用いると、チーム開発において以下のような利点があります。
- チーム内での理解の共有:統一されたHOCを利用することで、他の開発者がコードの意図や役割を把握しやすくなります。
- スケーラブルな拡張:アプリケーションが成長しても既存のHOCを活用して新しい機能を追加できます。
再利用性の高いコードは、プロジェクト全体の効率性を大きく向上させるため、HOCの活用は重要なスキルといえます。
HOCの構文と基本的な使い方
高階コンポーネント(HOC)は、Reactで特定のロジックや機能を再利用可能にするための構造です。HOCの構文はシンプルであり、Reactの関数型プログラミングスタイルに基づいています。ここでは、HOCの基本構文と使用例を解説します。
HOCの基本構文
HOCは、関数として定義され、引数として渡されたコンポーネントを拡張した新しいコンポーネントを返します。以下がその基本形です。
const withEnhancement = (WrappedComponent) => {
return (props) => {
// 追加ロジックや状態の操作
return <WrappedComponent {...props} />;
};
};
WrappedComponent
はラップされる元のコンポーネントであり、props
をそのまま渡すことで元の挙動を保持しつつ新しい機能を追加できます。
簡単なHOCの例
次に、HOCの基本的な使い方を示します。この例では、コンポーネントにクリック回数をカウントする機能を追加します。
import React, { useState } from "react";
// HOCの定義
const withClickCounter = (WrappedComponent) => {
return (props) => {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
return <WrappedComponent count={count} onClick={handleClick} {...props} />;
};
};
// 元のコンポーネント
const Button = ({ count, onClick }) => (
<button onClick={onClick}>Clicked {count} times</button>
);
// HOCで拡張
const EnhancedButton = withClickCounter(Button);
export default EnhancedButton;
このコードでは、Button
コンポーネントにクリック回数を数える機能をHOCを使って追加しています。元のButton
はそのまま使用でき、ロジックはHOCに分離されているため、再利用性が高まります。
HOCの利点
- 元のコンポーネントの不変性
元のコンポーネントを変更せずに機能を追加できるため、コードの保守性が向上します。 - ロジックの分離
複数のコンポーネントで共有できる共通のロジックを1箇所にまとめることができます。 - 柔軟な適用
必要に応じてHOCを適用したり、適用しない選択が可能です。
注意点
HOCを使用する際には、以下の点に留意する必要があります。
- Propsの衝突:HOC内で生成したPropsが、元のコンポーネントのPropsと競合しないよう注意してください。
- コンポーネント階層の増加:HOCは新しいコンポーネントを生成するため、過剰な使用はコンポーネント階層を深くし、パフォーマンスに影響を与える可能性があります。
以上のように、HOCの基本構文と使用方法を理解することで、Reactアプリケーションの再利用性を高める第一歩を踏み出すことができます。
実際のユースケース
高階コンポーネント(HOC)は、様々なシナリオで再利用性を高めるために活用されています。ここでは、認証機能を例にとり、HOCの実践的な使い方を解説します。認証機能をHOCで実装することで、認証ロジックを複数のコンポーネント間で簡単に共有できます。
認証機能をHOCで実装する
以下は、認証が必要なページコンポーネントをHOCでラップする例です。このHOCは、ユーザーが認証されていない場合にログインページへリダイレクトする機能を追加します。
import React from "react";
import { Navigate } from "react-router-dom";
// 認証HOCの定義
const withAuthentication = (WrappedComponent) => {
return (props) => {
const isAuthenticated = localStorage.getItem("authToken"); // 仮の認証チェック
if (!isAuthenticated) {
// 認証されていない場合、ログインページにリダイレクト
return <Navigate to="/login" />;
}
// 認証されている場合、元のコンポーネントをレンダリング
return <WrappedComponent {...props} />;
};
};
// 認証が必要なページコンポーネント
const ProtectedPage = () => {
return <h1>このページは認証が必要です</h1>;
};
// HOCでラップして機能を追加
const AuthenticatedPage = withAuthentication(ProtectedPage);
export default AuthenticatedPage;
コードの解説
- 認証チェック:
localStorage.getItem("authToken")
で簡易的に認証状態を確認しています。本番環境ではより安全な認証方法を用います(例: ReduxやReact Contextで認証情報を管理)。 - リダイレクト: 認証されていない場合、
<Navigate to="/login" />
を使ってログインページに遷移させます。 - 再利用性の向上: HOCとして定義することで、異なる複数のページコンポーネントに認証機能を簡単に適用できます。
HOCを適用した複数のページ例
例えば、以下のように異なるページコンポーネントに同じ認証ロジックを適用することができます。
const AdminPage = () => <h1>管理者ページ</h1>;
const DashboardPage = () => <h1>ダッシュボード</h1>;
const AuthenticatedAdminPage = withAuthentication(AdminPage);
const AuthenticatedDashboardPage = withAuthentication(DashboardPage);
これにより、コードの重複を排除し、認証ロジックを一箇所で管理できます。
HOCによる認証機能の利点
- ロジックの一元管理: 認証ロジックをHOC内に集約することで、変更が必要な場合でもHOCを修正するだけで済みます。
- コードの簡潔化: 各ページコンポーネントには認証ロジックを含める必要がなくなり、コードがシンプルになります。
- 柔軟性: 認証が必要なページにHOCを適用するだけで機能を追加できます。
このように、HOCを利用した認証機能の実装は、Reactアプリケーションにおいて非常に実用的なユースケースの一つです。他のシナリオにも応用可能な考え方として理解を深めておきましょう。
コンポーネントラップとPropsの活用
高階コンポーネント(HOC)は、特定のロジックを元のコンポーネントに追加するためにコンポーネントをラップする仕組みを提供します。その際、Props(プロパティ)はHOCの挙動を制御したり、元のコンポーネントに情報を渡す重要な役割を果たします。ここでは、コンポーネントのラップ方法とPropsの活用法について解説します。
コンポーネントのラップ
HOCを利用する際、元のコンポーネントをラップすることで、以下のように機能を拡張します。
const withLogger = (WrappedComponent) => {
return (props) => {
console.log("Rendered with props:", props);
return <WrappedComponent {...props} />;
};
};
// 元のコンポーネント
const DisplayMessage = ({ message }) => <h1>{message}</h1>;
// HOCでラップ
const EnhancedDisplayMessage = withLogger(DisplayMessage);
// 使用例
<EnhancedDisplayMessage message="Hello, World!" />;
この例では、withLogger
が元のDisplayMessage
コンポーネントをラップし、レンダリング時にPropsをログとして記録します。
Propsの動的操作
HOCは、元のコンポーネントに新しいPropsを動的に追加することができます。これにより、元のコンポーネントの挙動を拡張したり変更することが可能です。
const withAdditionalProps = (WrappedComponent) => {
return (props) => {
const newProps = {
extraInfo: "追加情報",
...props,
};
return <WrappedComponent {...newProps} />;
};
};
const InfoComponent = ({ extraInfo, originalInfo }) => (
<div>
<p>Original: {originalInfo}</p>
<p>Extra: {extraInfo}</p>
</div>
);
// HOCで拡張
const EnhancedInfoComponent = withAdditionalProps(InfoComponent);
// 使用例
<EnhancedInfoComponent originalInfo="元の情報" />;
この例では、extraInfo
という新しいPropsをHOCが生成し、元のコンポーネントに渡しています。
Propsのフィルタリング
時には、HOCが元のコンポーネントに渡すPropsを制限することも必要です。HOCを用いて不要なPropsを削除することができます。
const filterProps = (WrappedComponent) => {
return ({ sensitiveData, ...remainingProps }) => {
// sensitiveDataは削除し、残りのPropsを渡す
return <WrappedComponent {...remainingProps} />;
};
};
const DisplayUser = ({ username }) => <h1>User: {username}</h1>;
// HOCでフィルタリング
const SafeDisplayUser = filterProps(DisplayUser);
// 使用例
<SafeDisplayUser username="JohnDoe" sensitiveData="secret" />;
このコードでは、sensitiveData
はラップしたHOCで除外され、元のコンポーネントに渡されません。
Propsを利用した制御のメリット
- 柔軟な機能追加
HOCは、Propsを動的に変更することで元のコンポーネントの挙動を簡単にカスタマイズできます。 - 再利用性の向上
どのコンポーネントでもHOCを適用できるため、共通のロジックを簡単に再利用できます。 - 意図的な分離
ロジックをHOCで管理し、UIロジックから分離することでコードの見通しが良くなります。
HOCの注意点
- Propsの競合: HOCが追加するPropsと元のコンポーネントのProps名が重複しないように注意してください。
- パフォーマンス: 過剰なラップによるレンダリングコストの増加を防ぐため、必要な箇所にのみ適用することが重要です。
Propsを活用したHOCの使用により、Reactアプリケーションの再利用性と柔軟性を高めることが可能です。適切な設計で、保守性の高いコンポーネント構築を目指しましょう。
HOCの課題と解決策
高階コンポーネント(HOC)は、Reactの開発で再利用性を高めるための強力な手法ですが、設計や運用上いくつかの課題が存在します。ここでは、HOCを使用する際に直面しやすい問題と、それに対する解決策を解説します。
課題1: コンポーネントの階層が深くなる
HOCは新しいコンポーネントを生成するため、複数のHOCを連続して適用すると、コンポーネントの階層が深くなり、デバッグやパフォーマンスに影響を及ぼす可能性があります。
解決策
React DevTools
の活用
React DevToolsを使うと、HOCでラップされたコンポーネントの階層を視覚化しやすくなります。- HOCの連鎖を最小限に
必要以上に多くのHOCを適用しないよう設計を見直します。複数のHOCの機能を1つのHOCに統合することも検討してください。 displayName
の設定
デバッグ時にHOCの名前がわかりやすくなるよう、displayName
を設定します。
const withLogger = (WrappedComponent) => {
const ComponentWithLogger = (props) => {
console.log("Props:", props);
return <WrappedComponent {...props} />;
};
ComponentWithLogger.displayName = `WithLogger(${WrappedComponent.displayName || WrappedComponent.name || "Component"})`;
return ComponentWithLogger;
};
課題2: Propsの衝突
HOCが生成するPropsと元のコンポーネントのPropsが重複すると、意図しない動作が発生することがあります。
解決策
- Propsの名前空間を明確にする
HOCで追加するPropsの名前に一貫性を持たせ、元のコンポーネントと区別します。
const withUserInfo = (WrappedComponent) => {
return (props) => {
const userProps = { user: { name: "John", age: 30 } };
return <WrappedComponent {...props} userInfo={userProps} />;
};
};
- Propsのフィルタリング
不要なPropsや競合するPropsをHOC内でフィルタリングします。
課題3: 冗長なレンダリング
HOCで状態を管理する場合、不必要な再レンダリングが発生することがあります。これにより、アプリケーションのパフォーマンスが低下する可能性があります。
解決策
React.memo
の活用
ラップされたコンポーネントが受け取るPropsが変わらない場合、再レンダリングを防ぎます。
const MemoizedComponent = React.memo(WrappedComponent);
- 適切なレンダリング条件の設定
HOC内で状態やロジックの更新条件を明確にして、無駄な再レンダリングを回避します。
課題4: デバッグが難しい
HOCでロジックを隠蔽すると、デバッグが難しくなる場合があります。
解決策
- HOCの簡潔化
HOCで複雑なロジックを実装するのではなく、必要最低限の機能に留めます。複雑なロジックはカスタムフックなどで分離することも有効です。 - ログの追加
コンポーネントのライフサイクルやPropsの状態を追跡するために、HOC内で適切にログを記録します。
課題5: 代替技術の選択肢が増えた
Reactでは、HOCの代替としてカスタムフックが利用されるケースが増えており、HOCとどちらを使用すべきか迷うことがあります。
解決策
- 用途に応じた選択
- HOC: 見た目に影響を与えず、機能だけを追加する場合に適しています。
- カスタムフック: ロジックを分離し、コンポーネントの可読性を保ちたい場合に有効です。
- 組み合わせの検討
必要に応じてHOCとカスタムフックを組み合わせ、柔軟に設計します。
HOCの課題解決のポイント
HOCは非常に便利ですが、その使用には慎重な設計が求められます。適切なコンポーネントの階層管理、Propsの扱い方、デバッグ方法を工夫することで、Reactアプリケーションの再利用性と保守性をさらに向上させることができます。
HOCの応用例
高階コンポーネント(HOC)は、基本的な再利用性向上だけでなく、複雑な機能や特定の要件を効率的に実装するためにも活用できます。ここでは、具体的な応用例として、データフェッチとUIの状態管理をHOCで実現する方法を紹介します。
応用例1: データフェッチHOC
多くのアプリケーションでは、外部APIからデータを取得して表示することが必要です。HOCを使うことで、データフェッチロジックを共通化し、複数のコンポーネントで再利用できます。
import React, { useEffect, useState } from "react";
// データフェッチHOC
const withDataFetch = (WrappedComponent, fetchUrl) => {
return (props) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(fetchUrl);
if (!response.ok) {
throw new Error("データの取得に失敗しました");
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [fetchUrl]);
return (
<WrappedComponent
{...props}
data={data}
loading={loading}
error={error}
/>
);
};
};
// データ表示コンポーネント
const DataDisplay = ({ data, loading, error }) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return <pre>{JSON.stringify(data, null, 2)}</pre>;
};
// HOCでラップして機能を追加
const EnhancedDataDisplay = withDataFetch(DataDisplay, "https://jsonplaceholder.typicode.com/posts");
export default EnhancedDataDisplay;
この例では、データフェッチのロジックをHOCにカプセル化し、DataDisplay
に簡単に適用しています。他のコンポーネントでも異なるfetchUrl
を渡すことで、同じロジックを再利用可能です。
応用例2: UI状態管理HOC
特定のUI状態を管理するロジックもHOCで共通化できます。たとえば、モーダル表示のオン/オフやトグル状態の管理です。
import React, { useState } from "react";
// 状態管理HOC
const withToggle = (WrappedComponent) => {
return (props) => {
const [isToggled, setIsToggled] = useState(false);
const toggle = () => setIsToggled((prev) => !prev);
return <WrappedComponent {...props} isToggled={isToggled} toggle={toggle} />;
};
};
// モーダルコンポーネント
const Modal = ({ isToggled, toggle }) => (
<div>
<button onClick={toggle}>
{isToggled ? "Hide Modal" : "Show Modal"}
</button>
{isToggled && <div className="modal">This is a modal!</div>}
</div>
);
// HOCでラップ
const TogglableModal = withToggle(Modal);
export default TogglableModal;
この例では、トグル状態の管理をHOCに抽象化し、Modal
コンポーネントが直接状態管理を意識する必要をなくしています。
応用例3: アクセス制御HOC
特定のユーザー権限に応じてコンポーネントを表示制御する機能もHOCで簡単に実現できます。
const withPermission = (WrappedComponent, allowedRoles) => {
return ({ userRole, ...props }) => {
if (!allowedRoles.includes(userRole)) {
return <p>アクセス権限がありません</p>;
}
return <WrappedComponent {...props} />;
};
};
const AdminPage = () => <h1>管理者専用ページ</h1>;
const RestrictedAdminPage = withPermission(AdminPage, ["admin"]);
// 使用例
<RestrictedAdminPage userRole="user" />;
<RestrictedAdminPage userRole="admin" />;
この例では、userRole
を基にアクセス制御を行い、権限のないユーザーにはエラーメッセージを表示します。
HOC応用のメリット
- コードの重複削減
よく使われるロジックを共通化し、記述量を減らします。 - 柔軟性と拡張性
コンポーネントに必要な機能を柔軟に追加できます。 - メンテナンスの簡便化
一箇所の修正で複数コンポーネントに影響を与えることができ、保守性が向上します。
HOCは多くの場面で役立つ再利用性の高い手法であり、データフェッチ、UI状態管理、アクセス制御など、様々なシナリオで活用できます。適切な設計で、Reactプロジェクトを効率的に運用しましょう。
パフォーマンス最適化
高階コンポーネント(HOC)は再利用性を高める強力な手法ですが、適切に設計しないとアプリケーションのパフォーマンスに影響を与える可能性があります。ここでは、HOCを利用する際に注意すべきパフォーマンス課題とその最適化方法を解説します。
課題1: 不必要な再レンダリング
HOCで状態やロジックを追加した場合、元のコンポーネントが受け取るPropsや外部状態の変化により不必要な再レンダリングが発生することがあります。
解決策: `React.memo`の活用
React.memo
を使うことで、受け取るPropsが変更されない場合、再レンダリングをスキップできます。
const withLogger = (WrappedComponent) => {
const ComponentWithLogger = React.memo((props) => {
console.log("Props updated:", props);
return <WrappedComponent {...props} />;
});
return ComponentWithLogger;
};
const MyComponent = ({ text }) => <div>{text}</div>;
const EnhancedComponent = withLogger(MyComponent);
// Propsが同じ場合、レンダリングをスキップ
<EnhancedComponent text="Hello" />;
React.memo
をHOCの内部やラップするコンポーネントに適用することで、レンダリングを効率化します。
課題2: HOCのチェーンによるパフォーマンス低下
複数のHOCを連続的に適用すると、コンポーネントのネストが深くなり、レンダリングに影響を与える可能性があります。
解決策: 必要なHOCの統合
複数のHOCで実現しているロジックを1つに統合し、コンポーネントの階層を浅くします。
const withEnhancements = (WrappedComponent) => {
return (props) => {
const additionalData = "Enhanced Data";
const additionalLogic = () => console.log("Logic added");
return (
<WrappedComponent
{...props}
additionalData={additionalData}
additionalLogic={additionalLogic}
/>
);
};
};
統合されたHOCにより、ロジックはそのまま再利用可能で、レンダリングパフォーマンスも維持できます。
課題3: Propsの過剰渡し
HOCから元のコンポーネントに不要なPropsを渡してしまうと、メモリ消費やレンダリングコストが増大する場合があります。
解決策: Propsのフィルタリング
HOC内部で、渡すPropsを必要最小限に制限します。
const withFilteredProps = (WrappedComponent) => {
return ({ unnecessaryProp, ...filteredProps }) => {
return <WrappedComponent {...filteredProps} />;
};
};
const MyComponent = ({ importantProp }) => <div>{importantProp}</div>;
const FilteredComponent = withFilteredProps(MyComponent);
// unnecessaryPropはMyComponentに渡されません
<FilteredComponent importantProp="Necessary" unnecessaryProp="Unnecessary" />;
このようにすることで、余計なデータ処理を回避し、軽量なレンダリングを実現します。
課題4: 大量データの処理
HOC内で扱うデータが大きい場合、処理時間が増加し、ユーザー体験が悪化することがあります。
解決策: データのメモ化
useMemo
を使用して計算済みデータをキャッシュし、再計算を防ぎます。
const withExpensiveCalculation = (WrappedComponent) => {
return (props) => {
const processedData = React.useMemo(() => {
return props.data.map((item) => item * 2); // 高コストな計算
}, [props.data]);
return <WrappedComponent {...props} processedData={processedData} />;
};
};
この方法により、大量データの処理でも必要な場合にのみ再計算が行われます。
課題5: デバッグが困難になる
HOCを多用すると、コンポーネントの実際のレンダリング階層が複雑化し、パフォーマンス問題の原因を特定しにくくなります。
解決策: `React.Profiler`の活用
React.Profiler
を利用してレンダリング時間を測定し、ボトルネックを特定します。
<React.Profiler id="MyComponent" onRender={(id, phase, actualDuration) => {
console.log({ id, phase, actualDuration });
}}>
<EnhancedComponent />
</React.Profiler>
これにより、HOCがレンダリング時間に与える影響を測定できます。
HOC最適化のまとめ
HOCを効率的に運用するには、以下のポイントに留意してください。
- 再レンダリングを最小限に抑える(
React.memo
、useMemo
の活用)。 - 過剰なHOCチェーンを避ける。
- 不要なPropsの削除やデバッグツールの活用で構造を明確にする。
これらの最適化手法を活用することで、HOCを用いたReactアプリケーションのパフォーマンスを向上させることができます。
まとめ
本記事では、Reactにおける高階コンポーネント(HOC)の基礎から応用例、さらに課題とその解決策までを解説しました。HOCは、共通ロジックの再利用やUIの状態管理、データフェッチの効率化など、Reactアプリケーションの柔軟性を高める強力なツールです。
適切に設計すれば、コードの重複を減らし、保守性を向上させることができます。ただし、過剰なネストや不必要な再レンダリングといった課題に対処するため、React.memo
やuseMemo
などの最適化手法を併用することが重要です。
HOCを活用することで、スケーラブルで再利用性の高いReactアプリケーションを構築できるようになります。実際のプロジェクトで取り入れて、その効果を体感してください。
コメント