検索
ホームページウェブフロントエンドjsチュートリアルコンポーネントの間違いをやめてください

Stop Making These Component Mistakes

実のところ、コンポーネントは一見シンプルです。始めるのは簡単です。関数を定義し、JSX を返し、それを呼び出すだけです。しかし、クリーンで保守しやすく、快適に作業できるコンポーネントを作成するにはどうすればよいでしょうか?それは全く異なる球技です。

私たちは気づかないうちに次のようなコンポーネントを作成しています。

  • 大きすぎて一目では理解できません。
  • テストするのは非常に難しいです。
  • 非常に密接に結合されているため、再利用は不可能です。
  • パフォーマンスの判断が不十分なため、停滞しています。

この投稿では、開発者が React コンポーネントで犯す最も一般的な間違いについて説明します。さらに重要なことは、アプリ全体をバラバラにせずに問題を修正する方法を説明することです。

初心者でも、何年もの経験がある場合でも、これらのヒントは、機能するだけでなく保守が楽しいコンポーネントを作成するのに役立ちます。

「すべてのコンポーネント」のアンチパターン

私たち全員が犯す古典的な失敗、つまりすべてのコンポーネントについて話しましょう。あなたも見たことがありますが、最初は小さくて無邪気で、おそらく単純なフォームまたはダッシュボードとして始まります。少し早送りすると、状態を管理し、API 呼び出しを処理し、データをフォーマットし、場合によっては朝のコーヒーを淹れることもできます。

// Please, no more of this
const UserDashboard = () => {
  const [userData, setUserData] = useState(null);
  const [orders, setOrders] = useState([]);
  const [notifications, setNotifications] = useState([]);
  const [settings, setSettings] = useState({});
  const [isEditing, setIsEditing] = useState(false);
  const [activeTab, setActiveTab] = useState('profile');

  // 15 separate useEffects
  // 10 different event handlers
  // Multiple conditional renders
  // 300+ lines of chaos
};

聞き覚えがありますか?

自分が有罪かどうかを見分ける方法

次の場合、コンポーネントは「すべてのコンポーネント」になっている可能性があります。

  • 状態のオーバーロード: 3 ~ 4 つ以上の個別の状態を追跡しています。
  • 際限なくスクロールする: 特定の関数やロジックを探すのに時間がかかりすぎます。
  • 依存関係の肥大化: useEffect の依存関係は、毎週の買い物リストのようになります。
  • 機能のクリープ拒否: 機能がもう 1 つ増えても問題ない、と自分に言い聞かせます。

ブレイク・イット・ダウン

解決策は?すべてを単一のコンポーネントにする代わりに、責任をより小さく集中した部分に分割します。

// A cleaner, smarter approach
const UserDashboard = () => {
  return (
    <div>
      <userprofile></userprofile>
      <orderhistory></orderhistory>
      <notificationcenter></notificationcenter>
      <usersettings></usersettings>
    </div>
  );
};

重要な原則: ロジック >レイアウト

リファクタリングするときは、画面上の見た目に基づいてコンポーネントを分割しないでください。責任ごとに分けてください。この機能は独自のコンポーネントに値するか? 自問してください。ユーザー プロフィールや注文履歴など、何か別のものを処理している場合は、おそらく処理されます。

ヒント: 優れたコンポーネントは、1 つのことを適切に実行します。その目的を一文で説明するのが難しい場合は、やりすぎている可能性があります。

プロップドリル地獄

「小道具を渡す」というあまり面白くないゲームについて話しましょう。深くネストされた子に到達するためだけに同じプロップを複数のコンポーネントに渡したことがあれば、プロップドリル地獄にはまっていることになります。

// Please, no more of this
const UserDashboard = () => {
  const [userData, setUserData] = useState(null);
  const [orders, setOrders] = useState([]);
  const [notifications, setNotifications] = useState([]);
  const [settings, setSettings] = useState({});
  const [isEditing, setIsEditing] = useState(false);
  const [activeTab, setActiveTab] = useState('profile');

  // 15 separate useEffects
  // 10 different event handlers
  // Multiple conditional renders
  // 300+ lines of chaos
};

このアプローチは面倒なだけでなく、長期的な問題を引き起こします。ユーザー プロパティの名前を変更する必要があると想像してください。突然、5 か所以上で更新するようになりました。さらに悪いことに、コンポーネントを使用すらしていないデータに結び付けることになります。

これを修正する方法

小道具を使ってホットポテトをする必要はありません。ここでは、穴あけを完全に回避するための 2 つの実用的な解決策を紹介します。

1.共有データにコンテキストを使用する

アプリのさまざまな部分にまたがってデータにアクセスする場合、React の Context API を使用すると作業を簡素化できます。

// A cleaner, smarter approach
const UserDashboard = () => {
  return (
    <div>
      <userprofile></userprofile>
      <orderhistory></orderhistory>
      <notificationcenter></notificationcenter>
      <usersettings></usersettings>
    </div>
  );
};

2.柔軟性を高めるためにコンポジションを使用する

プロップをレイヤーに強制的に通すのではなく、必要なものだけを渡すようにコンポーネントを再構築します。

// This is exhausting
const App = () => {
  const [user, setUser] = useState({});
  return (
    <layout user="{user}">
      <sidebar user="{user}">
        <navigation user="{user}">
          <usermenu user="{user}"></usermenu>
        </navigation>
      </sidebar>
    </layout>
  );
};

重要なポイント

コンテキストは、ユーザー情報、テーマ、グローバル設定などのアプリ全体のデータに適しています。ただし、それが常に最善の選択肢であるとは限りません。使いすぎないでください。局所的な状態については、ドリル加工を完全に回避するようにコンポーネントの構造を調整できるかどうかを検討してください。

目標は、コンポーネントを明確にして保守しやすくすることです。小道具の穴あけを避けることで、時間、イライラ、そして将来の無数の頭痛の種を節約できます。

時期尚早な最適化の罠

時期尚早な最適化が諸悪の根源であるという有名な言葉を聞いたことがあるでしょう。さて、コンポーネントレベルの悪へようこそ。私が話しているのは、二度必要になるかどうかも分からないうちに、すべてを再利用可能にしようとするときのことです。

通常は次のようになります:

const UserContext = createContext();

const App = () => {
  const [user, setUser] = useState({});
  return (
    <usercontext.provider value="{user}">
      <layout>
        <sidebar>
          <navigation></navigation>
        </sidebar>
      </layout>
    </usercontext.provider>
  );
};

// Use it only where needed
const UserMenu = () => {
  const user = useContext(UserContext);
  return <div>{user.name}</div>;
};

コンポーネントを自然に進化させましょう。今日必要とわかっているものを構築します。新しい要件が発生した場合は、明確に正当化できるときに機能を追加してください。時期尚早な最適化は時間を無駄にし、複雑さを増し、ほとんど報われません。

覚えておいてください: YAGNI 原則 (You Aren’t Gonna Need It) はコンポーネントにも適用されます。最高の抽象化は、解決しようとしている問題に実際に遭遇したときに生まれます。過剰なエンジニアリングは積極的に行われるように感じるかもしれませんが、常にシンプルさが勝利します。

副作用の不始末

これは悪影響管理の典型的な例です。

// Focused components for better clarity
const Navigation = ({ children }) => {
  return <nav>{children}</nav>;
};

// Pass data only where required
const App = () => {
  const user = useUser();
  return (
    <layout>
      <navigation>
        <usermenu user="{user}"></usermenu>
      </navigation>
    </layout>
  );
};

よくある間違いと修正

1) 面倒なデータの取得

不適切なデータ処理は、解決するよりも多くのバグを生み出します。これはよりクリーンなアプローチです:

// Behold, the over-engineered button
const Button = ({ 
  children,
  variant = 'primary',
  size = 'medium',
  isFullWidth = false,
  isDisabled = false,
  isLoading = false,
  leftIcon,
  rightIcon,
  onClick,
  customClassName,
  style,
  loadingText = 'Loading...',
  tooltipText,
  animationType,
  // ... 10 more props
}) => {
  // 50 lines of prop processing logic
  return (
    <button classname="{generateComplexClassNames()}">



<h3>
  
  
  Why This Hurts
</h3>

<ul>
<li>Your “simple” button now requires an instruction manual.</li>
<li>Most of those 15+ props will never be used.</li>
<li>Making updates becomes risky because you have to account for endless combinations.</li>
<li>Writing tests becomes painful, with a hundred possible scenarios to consider.</li>
</ul>

<h3>
  
  
  Better Approach:
</h3>

<p>Instead of building for every imaginable scenario, start small and let your components grow as needed.<br>
</p>

<pre class="brush:php;toolbar:false">// Start simple
const Button = ({ children, onClick, variant = 'primary' }) => {
  return (
    <button classname="{`btn" btn- onclick="{onClick}">
      {children}
    </button>
  );
}

// Create specific buttons when you actually need them
const LoadingButton = ({ isLoading, children, ...props }) => {
  return (
    <button>
      {isLoading ? 'Loading...' : children}
    </button>
  );
}

2) クリーンアップを忘れる

後は必ず片付けてください:

const UserProfile = ({ userId }) => {  
  const [user, setUser] = useState(null);  
  const [posts, setPosts] = useState([]);  

  // Dependency array woes
  useEffect(() => {  
    fetchUserData(userId);  
    fetchUserPosts(userId);  
    // No cleanup? Yikes.
  }, []); // eslint-disable-line react-hooks/exhaustive-deps  

  // Multiple effects, all tangled
  useEffect(() => {  
    const subscription = subscribeToUserStatus(userId);  
  }, [userId]);  

  // Cleanup? What cleanup?
  useEffect(() => {  
    const interval = setInterval(checkNotifications, 5000);  
  }, []);  
};

3) 競合状態の無視

この手法を使用してリクエストの重複を避けます:

// Improved version
const UserProfile = ({ userId }) => {  
  const { data: user, isLoading } = useQuery(  
    ['user', userId],  
    () => fetchUserData(userId)  
  );  

  // Keep concerns separate
  const { data: posts } = useQuery(  
    ['posts', userId],  
    () => fetchUserPosts(userId),  
    { enabled: !!user }  
  );  
};

簡単なヒント

  • useEffect を使用する前に考えてください: 場合によっては、useEffect がまったく必要ない場合もあります。
  • 焦点を絞ってください: 1 つのエフェクトで 1 つの責任を処理する必要があります。
  • 常にクリーンアップ: サブスクリプション、間隔、イベント リスナーには注意が必要です。
  • 適切なツールを使用します。React Query のようなライブラリを使用すると、データのフェッチとキャッシュが簡素化されます。
  • eslint-disable で不正行為をしないでください。依存関係の問題を非表示にするのではなく、修正してください。

パフォーマンスの盲点

これらの卑劣なパフォーマンスの問題について話しましょう。彼らは、すべてがうまくいっているように見えるため、実際はそうではないときまで、目立たないように行動するタイプです。これらの静かな犯人を明らかにし、それらを修正する方法を見てみましょう。

問題

ここでは、パフォーマンスに微妙な落とし穴があるコンポーネントを示します。

// Please, no more of this
const UserDashboard = () => {
  const [userData, setUserData] = useState(null);
  const [orders, setOrders] = useState([]);
  const [notifications, setNotifications] = useState([]);
  const [settings, setSettings] = useState({});
  const [isEditing, setIsEditing] = useState(false);
  const [activeTab, setActiveTab] = useState('profile');

  // 15 separate useEffects
  // 10 different event handlers
  // Multiple conditional renders
  // 300+ lines of chaos
};

問題を見つけられますか?それらを詳しく見てみましょう。

修正

1) 高価な計算をメモ化する

レンダリングごとにすべてを再計算する代わりに、useMemo を使用して結果をキャッシュします。

// A cleaner, smarter approach
const UserDashboard = () => {
  return (
    <div>
      <userprofile></userprofile>
      <orderhistory></orderhistory>
      <notificationcenter></notificationcenter>
      <usersettings></usersettings>
    </div>
  );
};

これにより、レンダリングのたびにデータの再計算やイベント ハンドラーの再作成が回避されます。また、メモを使用した子コンポーネントの不必要な再レンダリングも防ぎます。

2) 効率的な状態更新

状態管理が不十分だと、パフォーマンスが低下する可能性もあります。検索結果などの更新を処理するより良い方法は次のとおりです:

// This is exhausting
const App = () => {
  const [user, setUser] = useState({});
  return (
    <layout user="{user}">
      <sidebar user="{user}">
        <navigation user="{user}">
          <usermenu user="{user}"></usermenu>
        </navigation>
      </sidebar>
    </layout>
  );
};

デバウンスにより、キーストロークごとにデータを取得することがなくなり、不必要な API 呼び出しや再レンダリングが削減されます。

パフォーマンスに関する簡単なヒント

  • メモ化を多用しないでください。最適化する価値がある場合にのみ最適化してください。
  • インライン関数を避ける: 安定した参照によりパフォーマンスが向上します。
  • プロップを予測可能に保つ: 浅くて安定したプロップは、コンポーネントの効率を維持するのに役立ちます。
  • 大きなリストを分割する:react-window のようなツールは、大きなデータセットを適切に処理できます。
  • 状態を近づける: 実際に必要な状態のみを管理します。
  • DevTools を使用したプロファイル: 最適化する前に必ず測定します。

結論

コンポーネントの構築はロケット科学ではありませんが、正直に言いましょう。悪い習慣につまずいてしまうのは簡単です。私はこれらすべての間違いを犯してきました(そして今でも時々犯します)。大丈夫です。重要なのは、それらを早期に発見し、修正し、粗雑なコードベースを避けることです。

より良いコンポーネントのためのクイックチェックリスト

✅ 単一の責任: コンポーネントのジョブを一文で要約できない場合は、コンポーネントを分解してください。

✅ 小道具の管理: 小道具をレイヤーの上にレイヤーを介して渡しますか?代わりにコンテキストを使用するか、合成を活用することを検討してください。

✅ 状態とエフェクト: エフェクトに焦点を当て、適切にクリーンアップし、最新のツールで複雑なデータの取得を処理させます。

✅ パフォーマンス: 目的のために最適化するのではなく、まず測定してください。必要に応じて、memo、useMemo、useCallback などのツールを賢く使用してください。

✅ シンプルに始める: いつか起こるかもしれない問題ではなく、今抱えている問題を解決してください。

最高のコンポーネントとは、派手でも賢すぎるものでもありません。チームが 6 か月後にうめき声を上げることなく読み、保守できるコンポーネントです。

覚えておいてください: これらは難しいルールではなく、単なるガイドラインです。時々壊れてしまうこともありますが、それはまったく問題ありません。目標は完璧ではありません。後でキャリアの選択を見直したときに、自分のキャリアの選択に疑問を抱かないようにするためのコンポーネントを構築することです。

以上がコンポーネントの間違いをやめてくださいの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptの文字列文字を交換しますJavaScriptの文字列文字を交換しますMar 11, 2025 am 12:07 AM

JavaScript文字列置換法とFAQの詳細な説明 この記事では、javaScriptの文字列文字を置き換える2つの方法について説明します:内部JavaScriptコードとWebページの内部HTML。 JavaScriptコード内の文字列を交換します 最も直接的な方法は、置換()メソッドを使用することです。 str = str.replace( "find"、 "置換"); この方法は、最初の一致のみを置き換えます。すべての一致を置き換えるには、正規表現を使用して、グローバルフラグGを追加します。 str = str.replace(/fi

独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか?独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか?Mar 18, 2025 pm 03:12 PM

記事では、JavaScriptライブラリの作成、公開、および維持について説明し、計画、開発、テスト、ドキュメント、およびプロモーション戦略に焦点を当てています。

ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか?ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか?Mar 18, 2025 pm 03:14 PM

この記事では、ブラウザでJavaScriptのパフォーマンスを最適化するための戦略について説明し、実行時間の短縮、ページの負荷速度への影響を最小限に抑えることに焦点を当てています。

jQueryマトリックス効果jQueryマトリックス効果Mar 10, 2025 am 12:52 AM

マトリックスの映画効果をあなたのページにもたらしましょう!これは、有名な映画「The Matrix」に基づいたクールなJQueryプラグインです。プラグインは、映画の古典的な緑色のキャラクター効果をシミュレートし、画像を選択するだけで、プラグインはそれを数値文字で満たされたマトリックススタイルの画像に変換します。来て、それを試してみてください、それはとても面白いです! それがどのように機能するか プラグインは画像をキャンバスにロードし、ピクセルと色の値を読み取ります。 data = ctx.getimagedata(x、y、settings.greasize、settings.greasize).data プラグインは、写真の長方形の領域を巧みに読み取り、jQueryを使用して各領域の平均色を計算します。次に、使用します

ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか?ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか?Mar 18, 2025 pm 03:16 PM

この記事では、ブラウザ開発者ツールを使用した効果的なJavaScriptデバッグについて説明し、ブレークポイントの設定、コンソールの使用、パフォーマンスの分析に焦点を当てています。

シンプルなjQueryスライダーを構築する方法シンプルなjQueryスライダーを構築する方法Mar 11, 2025 am 12:19 AM

この記事では、jQueryライブラリを使用してシンプルな画像カルーセルを作成するように導きます。 jQuery上に構築されたBXSLiderライブラリを使用し、カルーセルをセットアップするために多くの構成オプションを提供します。 今日、絵のカルーセルはウェブサイトで必須の機能になっています - 1つの写真は千の言葉よりも優れています! 画像カルーセルを使用することを決定した後、次の質問はそれを作成する方法です。まず、高品質の高解像度の写真を収集する必要があります。 次に、HTMLとJavaScriptコードを使用して画像カルーセルを作成する必要があります。ウェブ上には、さまざまな方法でカルーセルを作成するのに役立つ多くのライブラリがあります。オープンソースBXSLiderライブラリを使用します。 BXSLiderライブラリはレスポンシブデザインをサポートしているため、このライブラリで構築されたカルーセルは任意のものに適合させることができます

JavaScriptによる構造マークアップの強化JavaScriptによる構造マークアップの強化Mar 10, 2025 am 12:18 AM

キーポイントJavaScriptを使用した構造的なタグ付けの強化は、ファイルサイズを削減しながら、Webページコンテンツのアクセシビリティと保守性を大幅に向上させることができます。 JavaScriptを効果的に使用して、Cite属性を使用して参照リンクを自動的にブロック参照に挿入するなど、HTML要素に機能を動的に追加できます。 JavaScriptを構造化されたタグと統合することで、ページの更新を必要としないタブパネルなどの動的なユーザーインターフェイスを作成できます。 JavaScriptの強化がWebページの基本的な機能を妨げないようにすることが重要です。 高度なJavaScriptテクノロジーを使用できます(

Angularを使用してCSVファイルをアップロードおよびダウンロードする方法Angularを使用してCSVファイルをアップロードおよびダウンロードする方法Mar 10, 2025 am 01:01 AM

データセットは、APIモデルとさまざまなビジネスプロセスの構築に非常に不可欠です。これが、CSVのインポートとエクスポートが頻繁に必要な機能である理由です。このチュートリアルでは、Angular内でCSVファイルをダウンロードおよびインポートする方法を学びます

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、