この記事では、よりクリーンな React コンポーネントを記述し、プロジェクトをより適切に拡張するのに役立ついくつかの簡単なテクニックを紹介します。 スプレッド演算子を使用してプロパティを渡すのは避けてくださいまず、避けるべきアンチパターンから始めましょう。明確な理由がない限り、スプレッド演算子 (例: { ...props }) を使用してコンポーネント ツリーを介して props を渡すことは避けてください。 この方法でプロパティを渡すと、コンポーネントの記述が速くなります。しかし、これによりコード内のバグを見つけることも難しくなります。そうすると、作成したコンポーネントに対する信頼が失われ、コンポーネントのリファクタリングが困難になり、デバッグが困難なバグが発生する可能性があります。 関数パラメータをオブジェクトにカプセル化する関数が複数のパラメータを受け入れる場合、それらをオブジェクトにカプセル化するのが最適です。例えば: エクスポートconst sampleFunction = ({ param1, param2, param3 }) => { コンソールにログ出力します。 } このように関数シグネチャを記述することには、いくつかの大きな利点があります。
イベント処理関数の場合、処理関数を関数の戻り値として使用します。関数型プログラミングに精通している場合、このプログラミング手法は、いくつかのパラメータが事前に設定されているため、関数のカリー化に似ていることがわかります。 次の例を見てみましょう。 'react' から React をインポートします デフォルトの関数 SampleComponent({ onValueChange }) をエクスポートします。 const handleChange = (キー) => { 戻り値 (e) => onValueChange(キー、e.target.value) } 戻る ( <フォーム> <input onChange={handleChange('name')} /> <input onChange={handleChange('email')} /> <input onChange={handleChange('phone')} /> </フォーム> ) } ご覧のとおり、このようにハンドラー関数を記述すると、コンポーネント ツリーが簡潔になります。 コンポーネントのレンダリングではif/elseの代わりにマップを使用しますカスタム ロジックに基づいてさまざまな要素をレンダリングする必要がある場合は、if/else ステートメントの代わりに map を使用することをお勧めします。 以下は if/else を使用した例です。 'react' から React をインポートします const Student = ({ name }) => <p>生徒名: {name}</p> const Teacher = ({ name }) => <p>教師名: {name}</p> const Guardian = ({ name }) => <p>ガーディアン名: {name}</p> デフォルト関数 SampleComponent({ user }) をエクスポートします。 コンポーネントを Student にします。 if (user.type === '教師') { コンポーネント = 教師 } それ以外の場合 (user.type === 'guardian') { コンポーネント = ガーディアン } 戻る ( <div> <コンポーネント名={user.name} /> </div> ) } 以下は map を使用した例です。 'react' から React をインポートします const Student = ({ name }) => <p>生徒名: {name}</p> const Teacher = ({ name }) => <p>教師名: {name}</p> const Guardian = ({ name }) => <p>ガーディアン名: {name}</p> 定数COMPONENT_MAP = { 学生: 学生、 先生:先生、 ガーディアン: ガーディアン } デフォルト関数 SampleComponent({ user }) をエクスポートします。 const コンポーネント = COMPONENT_MAP[user.type] 戻る ( <div> <コンポーネント名={user.name} /> </div> ) } この簡単な戦略を使用すると、コンポーネントをより読みやすく、理解しやすくすることができます。また、論理的な拡張も容易になります。 フックコンポーネントこのモードは、悪用されない限り非常に便利です。 アプリケーションでは多くのコンポーネントを使用することになる場合があります。機能するために状態が必要な場合は、その状態を提供するフックでラップできます。これらのコンポーネントの良い例としては、ポップアップ、トースト通知、シンプルなモーダル ダイアログなどがあります。たとえば、単純な確認ダイアログのフック コンポーネントを次に示します。 'react' から React をインポートします。{useCallback、useState }。 'components/global/ConfirmationDialog' から ConfirmationDialog をインポートします。 デフォルト関数 useConfirmationDialog({ をエクスポートする ヘッダーテキスト、 本文、 確認ボタンテキスト、 確認クリック時、 }) { 定数[isOpen, setIsOpen] = useState(false); 定数 onOpen = () => { setIsOpen(true); }; 定数ダイアログ = useCallback( () => ( <確認ダイアログ ヘッダーテキスト={ヘッダーテキスト} 本文={本文} isOpen={isOpen} onConfirmClick={onConfirmClick} onCancelClick={() => setIsOpen(false)} 確認ボタンテキスト={確認ボタンテキスト} /> )、 [開く] ); 戻る { ダイアログ、 オープン時、 }; } フック コンポーネントは次のように使用できます。 「react」からReactをインポートします。 './useConfirmationDialog' から { useConfirmationDialog } をインポートします。 関数クライアント() { const { ダイアログ、onOpen } = useConfirmationDialog({ headerText: "このレコードを削除しますか?" 本文: 「このレコードを削除してもよろしいですか? 元に戻すことはできません。」 確認ボタンテキスト:「削除」、 onConfirmClick: handleDeleteConfirm、 }); 関数handleDeleteConfirm() { //TODO: 削除 } const handleDeleteClick = () => { オープン時(); }; 戻る ( <div> <ダイアログ /> <ボタンのonClick={handleDeleteClick} /> </div> ); } デフォルトのクライアントをエクスポートします。 このようにコンポーネントを抽出すると、状態管理のために大量の定型コードを記述する必要がなくなります。 React フックについて詳しく知りたい場合は、私の投稿をご覧ください。 コンポーネントの分離次の 3 つのヒントは、コンポーネントを巧みに分割する方法に関するものです。私の経験では、コンポーネントをシンプルに保つことが、プロジェクトを管理しやすくするための最善の方法です。 ラッパーの使用複雑なコンポーネントを分解する方法を見つけるのに苦労している場合は、コンポーネントの各要素が提供する機能を確認してください。一部の要素は、ドラッグ アンド ドロップなどの独自の機能を提供します。 以下は react-beautiful-dnd を使用してドラッグ アンド ドロップを実装するコンポーネントの例です。 'react' から React をインポートします 'react-beautiful-dnd' から { DragDropContext, Droppable } をインポートします。 デフォルト関数DraggableSample()をエクスポートする{ 関数handleDragStart(結果) { console.log({ 結果 }); } 関数handleDragUpdate({ destination }) { console.log({ 宛先 }); } const handleDragEnd = ({ ソース、 宛先 }) => { console.log({ ソース、 宛先 }); }; 戻る ( <div> <ドラッグドロップコンテキスト onDragEnd={handleDragEnd} onDragStart={handleDragStart} onDragUpdate={handleDragUpdate} > <ドロップ可能 droppableId="ドロップ可能" 方向="水平" > {(提供) => ( <div {...provided.droppableProps} ref={provided.innerRef}> {columns.map((列, インデックス) => { 戻る ( <列コンポーネント キー={インデックス} 列={列} /> ); })} </div> )} </ドロップ可能> </ドラッグドロップコンテキスト> </div> ) } 次に、すべてのドラッグ ロジックをラッパーに移動した後のコンポーネントを見てみましょう。 'react' から React をインポートします デフォルト関数DraggableSample()をエクスポートする{ 戻る ( <div> <ドラッグラッパー> {columns.map((列, インデックス) => { 戻る ( <ColumnComponent キー = {インデックス} 列 = {列} /> ); })} </ドラッグラッパー> </div> ) } ラッパーのコードは次のとおりです。 'react' から React をインポートします 'react-beautiful-dnd' から { DragDropContext, Droppable } をインポートします。 デフォルトの関数DragWrapper({children})をエクスポートします。 関数handleDragStart(結果) { console.log({ 結果 }); } 関数handleDragUpdate({ destination }) { console.log({ 宛先 }); } const handleDragEnd = ({ ソース、 宛先 }) => { console.log({ ソース、 宛先 }); }; 戻る ( <ドラッグドロップコンテキスト onDragEnd={handleDragEnd} onDragStart={handleDragStart} onDragUpdate={handleDragUpdate} > <ドロップ可能 droppableId="ドロップ可能" direction="水平"> {(提供) => ( <div {...provided.droppableProps} ref={provided.innerRef}> {子供たち} </div> )} </ドロップ可能> </ドラッグドロップコンテキスト> ) } したがって、コンポーネントの機能をより高いレベルで確認する方が直感的になります。ドラッグのすべての機能はラッパー内にあるため、コードを理解しやすくなります。 関心の分離これは、大きなコンポーネントを分解するための私のお気に入りの方法です。 React の観点から見ると、関心の分離とは、データの取得と変更を担当するコンポーネントの部分と、要素の表示のみを担当する部分を分離することを意味します。 この関心の分離がフックを導入する主な理由です。カスタム フックを使用して、すべてのメソッドまたはグローバル状態に接続されたロジックをカプセル化できます。 たとえば、次のコンポーネントを見てみましょう。 'react' から React をインポートします './API' から { someAPICall } をインポートします。 './ItemDisplay' から ItemDisplay をインポートします。 デフォルト関数SampleComponent()をエクスポートします。 const [データ、setData] = useState([]) 使用効果(() => { someAPICall().then((結果) => { setData(結果)}) }, []) 関数 handleDelete() { console.log('削除!'); } 関数 handleAdd() { console.log('追加!'); } const handleEdit = () => { console.log('編集!'); }; 戻る ( <div> <div> {data.map(item => <ItemDisplay item={item} />)} </div> <div> <ボタンのクリック={handleDelete} /> <ボタンのクリック時={handleAdd} /> <ボタン onClick={handleEdit} /> </div> </div> ) } 以下は、カスタム フックによって分割されたコードを使用したリファクタリングされたバージョンです。 'react' から React をインポートします './ItemDisplay' から ItemDisplay をインポートします。 デフォルト関数SampleComponent()をエクスポートします。 const { データ、handleDelete、handleEdit、handleAdd } = useCustomHook() 戻る ( <div> <div> {data.map(item => <ItemDisplay item={item} />)} </div> <div> <ボタンのクリック={handleDelete} /> <ボタンのクリック時={handleAdd} /> <ボタン onClick={handleEdit} /> </div> </div> ) } フック自体のコードは次のとおりです。 './API' から { someAPICall } をインポートします。 エクスポートconst useCustomHook = () => { const [データ、setData] = useState([]) 使用効果(() => { someAPICall().then((結果) => { setData(結果)}) }, []) 関数 handleDelete() { console.log('削除!'); } 関数 handleAdd() { console.log('追加!'); } const handleEdit = () => { console.log('編集!'); }; 戻り値: { handleEdit、handleAdd、handleDelete、data } } 各コンポーネントは個別のファイルとしてパッケージ化されています通常、次のようなコードが書かれます。 'react' から React をインポートします エクスポートデフォルト関数SampleComponent({データ}) { const ItemDisplay = ({名前、日付}) => ( <div> <h3>{名前}</h3> <p>{日付}</p> </div> ) 戻る ( <div> <div> {data.map(item => <ItemDisplay item={item} />)} </div> </div> ) } React コンポーネントをこのように記述することに問題はありませんが、良い方法ではありません。 ItemDisplay コンポーネントを別のファイルに移動すると、コンポーネントが疎結合になり、拡張しやすくなります。 ほとんどの場合、クリーンで整然としたコードを書くには、適切なパターンに従い、アンチパターンを避けるように注意し、時間をかける必要があります。したがって、時間をかけてこれらのパターンに従うと、クリーンな React コンポーネントを作成するのに役立ちます。これらのパターンは私のプロジェクトで非常に役立っており、皆さんもそう感じていただければ幸いです。 以上が、簡潔なReactコンポーネントを書くためのヒントの詳細です。Reactコンポーネントを書くためのヒントの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: Dockerはdockerfileを使用してnode.jsアプリケーションを起動します
>>: mysql 結合クエリ (左結合、右結合、内部結合)
目次レスト演算子とは何ですか? JavaScript 関数では REST 演算子はどのように機能しま...
ここではCentOS7が使用されており、カーネルバージョンは [root@localhost ~]#...
序文ご存知のとおり、Linux ではハードディスクやグラフィック カードなどすべてがファイルです。 ...
目次CentOS7環境での設定コマンド手順1. DHCP設定ファイルを設定する2. グローバル構成を...
この記事は、この時期の「ピーターから奪ってポールに払う」という仕事のスタイルに対する私の不満から生ま...
かつて、サイコロを振るゲームについて話しました。その時は、steps 属性 + スプライト画像を使用...
1. まず、CSS3 のターゲット セレクターを使用し、a タグを使用して id セレクターを指定し...
デフォルトでは、CentOS 7 上の PHP は apache または nobody として実行さ...
序文Linux のファイル権限管理はとにかく素晴らしいです。SUID、SGID、SBIT の機能を確...
JavaScript は現在、毎年新しいバージョンがリリースされており、より便利で効率的な新しい演算...
初心者の Linux ユーザーとして、私は単純なgcc/g++操作を何度も使用してきましたが、少し複...
この記事では、3Dカルーセル効果をjsで実装するための具体的なコードを参考までに共有します。具体的な...
1. 分散ストレージシステムの概要情報技術の継続的な発展により、利便性がもたらされる一方で、データ量...
UPD 2020.2.26 現在、Ubuntu 20.04 LTSはまだリリースされていないため、チ...
目次1. セットとは何か2. セットコンストラクタ2.1) 配列2.2) 文字列2.3) 議論2.4...