React Hook の使用例 (一般的なフック 6 つ)

React Hook の使用例 (一般的なフック 6 つ)

1. useState: 関数コンポーネントに状態を持たせる

使用例:

// カウンター import { useState } from 'react'
定数テスト = () => {
    定数[count, setCount] = useState(0);
    戻る (
        <>
            <h1>クリック回数が{count}回</h1>
            <button onClick={() => setCount(count + 1)}>+1</button>
        </>
    );
}
デフォルトのエクスポートテスト

PS: クラス コンポーネントでは、this.setState が状態をマージして更新しますが、useState では、setState が状態を置き換えます。例えば:

// エラー例 import { useState } from 'react'
定数テスト = () => {
    const [counts, setCounts] = useState({
        数値1: 0,
        数値2: 0
    });
    戻る (
        <>
            <h1>num1:{counts.num1}</h1>
            <h1>num2: {counts.num2}</h1>
            <button onClick={() => setCounts({ num1: counts.num1 + 1})}>num1+1</button>
            <button onClick={() => setCounts({ num2: counts.num2 + 1})}>num2+1</button>
        </>
    );
}
デフォルトのエクスポートテスト

useState 内の setState が置き換えられ、マージされず、正しく更新されていることがわかります。

'react' から {useState} をインポートします。
定数テスト = () => {
    const [counts, setCounts] = useState({
        数値1: 0,
        数値2: 0
    });
    戻る (
        <>
            <h1>num1:{counts.num1}</h1>
            <h1>num2: {counts.num2}</h1>
            <button onClick={() => setCounts({ ...counts, num1: counts.num1 + 1})}>num1+1</button>
            <button onClick={() => setCounts({ ...counts, num2: counts.num2 + 1})}>num2+1</button>
        </>
    );
}
デフォルトのエクスポートテスト

2. useEffect: 副作用、ライフサイクルの置き換え

使用例として、クラス コンポーネントで、コンポーネントがマウントされた後とデータが更新された後に同じことを行う必要がある場合は、次のようにします。

コンポーネントマウント() {
    // 何かする }
コンポーネントを更新しました() {
    // 何かする }

ロジックが複雑だと、コードが洗練されていないように見え、論理的な混乱を引き起こしやすくなることがわかります。

使用効果(() => {
    // 何かする });

ここまでで、useEffect の基本的な使い方を見てきました。さらに、更新をトリガーする依存状態をバインドすることもできます。デフォルトでは、状態のデータが変更されると、次のような副作用が実行されます。

'react' から { useState, useEffect } をインポートします。
定数テスト = () => {
    定数[count1, setCount1] = useState(0);
    定数[count2, setCount2] = useState(0);
    使用効果(() => {
        console.log('useEffect がトリガーされました')
    });
    戻る (
        <>
            <h1>カウント1:{カウント1}</h1>
            <h1>カウント2:{カウント2}</h1>
            <button onClick={() => setCount1(count1 + 1)}>count1+1</button>
            <button onClick={() => setCount2(count2 + 1)}>count2+1</button>
        </>
    );
}
デフォルトのエクスポートテスト

上記のコードの useEffect の 2 番目のパラメータを、バインドする状態に渡します。複数の状態をバインドできます。

// 構文: useEffect(コールバック関数、[依存関係の値])
使用効果(() => {
    console.log('useEffect がトリガーされました')
}, [count1]); 

ご覧のとおり、バインドされた count1 が変更された場合にのみトリガーされます。空の配列が渡された場合、状態の変更はトリガーされません。このとき、useEffect の役割はクラスコンポーネントの componentDidMount に似ているため、リクエストの送信は通常ここで実行されます。

副作用の除去

上記の操作では、副作用をクリーンアップする必要はありません。ただし、一部の副作用はクリーンアップする必要があります。クリーンアップに失敗すると、例外が発生したり、メモリリークが発生したりします。たとえば、タイマーがオンになっている場合、クリーンアップしないと複数回オンになります。上記から、useEffect の最初のパラメーターはコールバック関数であり、コールバック関数で関数を返すことができることがわかります。この関数は、状態が更新された後、最初のコールバック関数が実行される前に呼び出すことができます。具体的な実装は次のとおりです。

使用効果(() => {
    // 副作用を設定する return () => {
        // 副作用をクリーンアップする }
});

3. useContext: コンポーネント間でデータを共有する

React.createContext(); TestContextオブジェクトを作成する
TestContext.Providerは、サブコンポーネントデータを<TestContext.Provider value={value}>の値にラップし、サブコンポーネント内のuseContext(TestContext)を通じて値を取得します。

'react' から React をインポートします。{useContext、useState }。
React の TestContext を作成します。
定数親 = () => {
    const [値、setValue] = useState(0);
    戻る (
        <div>
            {(() => console.log("親レンダリング"))()}
            <button onClick={() => setValue(value + 1)}>値 + 1</button>
            <TestContext.Provider 値 = {値}>
                <子供1 />
                <子供2 />
            </テストコンテキスト.プロバイダー>
        </div>
    );
}
定数Child1 = () => {
    定数値 = useContext(TestContext);
    戻る (
        <div>
            {(() => console.log('Child1-render'))()}
            <h3>子1の値: {値}</h3>
        </div>
    );
}
定数Child2 = () => {
    戻る (
        <div>
            {(() => console.log('Child2-render'))()}
            <h3>子供2</h3>
        </div>
    );
}
デフォルトの親をエクスポート

ここまではデータが共有されていますが、TestContext の共有データが変更されると、子コンポーネントが再レンダリングされることがわかります。Child2 はデータにバインドされておらず、意味のないレンダリングは行いません。React.memo を使用してこれを解決し、実装できます。

定数Child2 = React.memo(() => {
    戻る (
        <div>
            {(() => console.log('Child2-render'))()}
            <h3>子供2</h3>
        </div>
    );
}); 

4. useCallback: パフォーマンスの最適化

文法:

// useCallback(コールバック関数、[依存関係の値])
定数handleClick = useCallback(()=> {
    // 何かする }, [値]);

useCallback はメモ化された関数を返します。依存関係が変更されていない場合、複数回定義されても同じ値が返されます。その実装原理は、関数がパラメータセットで初めて呼び出されたときに、パラメータと計算結果がキャッシュされることです。関数が同じパラメータで再度呼び出されると、対応するキャッシュされた結果が直接返されます。

パフォーマンスの最適化の例:

'react' から React、{useState、useCallback、memo} をインポートします。
定数親 = () => {
    定数[値1、setValue1] = useState(0);
    定数[値2、setValue2] = useState(0);
    定数handleClick1 = useCallback(()=> {
        値1を1に設定します。
    }, [値1]);
    定数handleClick2 = useCallback(()=> {
        値2を1に設定します。
    }, [値2]);
    戻る (
        <>
            {(() => console.log("親レンダリング"))()}
            <h3>{値1}</h3>
            <h3>{値2}</h3>
            <Child1 ハンドルクリック1 = {ハンドルクリック1} />
            <Child2 ハンドルクリック2 = {ハンドルクリック2} />
        </>
    );
}
定数Child1 = メモ(props => {
    戻る (
        <div>
            {(() => console.log("Child1-render"))()}
            <button onClick={() => props.handleClick1()}>value1 + 1</button>
        </div>
    );
});
定数Child2 = メモ(props => {
    戻る (
        <div>
            {(() => console.log("Child2-render"))()}
            <button onClick={() => props.handleClick2()}>value2 + 1</button>
        </div>
    );
});
デフォルトの親をエクスポート

useCallback はメモ化されたコールバック関数を返します。この関数は、バインドされた依存関係の 1 つが変更された場合にのみ変更され、不要なレンダリングを防止します。コンポーネント間のデータ共有の例として使用されているイベントは、親コンポーネントのクリックによってトリガーされますが、ここでは状態の昇格を使用して、子コンポーネントが呼び出す親コンポーネントのメソッドを渡しています。この関数もレンダリングされるたびに変更されるため、子コンポーネントが再レンダリングされます。上記の例では、useCallback が関数をラップし、依存する値が変更されていない場合はキャッシュされた関数を返します。React.memo を使用すると、無意味なレンダリングを最適化できます。

5. useMemo: パフォーマンスの最適化

文法:

// useMemo(コールバック関数、[依存関係の値])
メモを使う(() => {
    // 何かする },[値]);

例を見てみましょう:

React をインポートし、{useState} を 'react' から取得します。
定数テスト = ()=> {
    const [値、setValue] = useState(0);
    定数[count, setCount] = useState(1);
    定数 getDoubleCount = () => {
        console.log('getDoubleCountが計算されました');
        カウント * 2 を返します。
    };
    戻る (
        <div>
            <h2>値: {値}</h2>
            <h2>ダブルカウント: {getDoubleCount()}</h2>
            <button onClick={() => setValue(value + 1)}>value+1</button>
        </div>
    )
}
デフォルトのエクスポートテスト

getDoubleCount は count に依存しますが、値が変更されると再計算されてレンダリングされることがわかります。次に、次のように getDoubleCount を useMemo でラップするだけです。

React をインポートし、{useState、useMemo} を 'react' からインポートします。
定数テスト = ()=> {
    const [値、setValue] = useState(0);
    定数[count, setCount] = useState(1);
    定数 getDoubleCount = useMemo(() => {
        console.log('getDoubleCountが計算されました');
        カウント * 2 を返します。
    }、[カウント]);
    戻る (
        <div>
            <h2>値: {値}</h2>
            <h2>ダブルカウント: {getDoubleCount}</h2>
            <button onClick={() => setValue(value + 1)}>value+1</button>
        </div>
    )
}
デフォルトのエクスポートテスト

これで、getDoubleCount は依存カウントが変更された場合にのみ再計算してレンダリングするようになります。

useMemo と useCallback の共通点:

  • 受け取ったパラメータは同じで、最初のものはコールバック関数、2番目のものは依存データです。
  • これらはすべて、依存データが変更されると結果を再計算し、キャッシュの役割を果たします。

useMemo と useCallback の違い:

  • useMemoの計算結果は戻り値であり、通常は計算結果の値をキャッシュするために使用されます。
  • useCallbackの計算結果は関数であり、通常は関数のキャッシュに使用されます。

6. useRef の使用: たとえば、ボタンをクリックして入力ボックスにフォーカスを当てるには、次のようにします。

React をインポートし、{useState、useMemo} を 'react' からインポートします。
定数テスト = ()=> {
    const [値、setValue] = useState(0);
    定数[count, setCount] = useState(1);
    定数 getDoubleCount = useMemo(() => {
        console.log('getDoubleCountが計算されました');
        カウント * 2 を返します。
    }、[カウント]);
    戻る (
        <div>
            <h2>値: {値}</h2>
            <h2>ダブルカウント: {getDoubleCount}</h2>
            <button onClick={() => setValue(value + 1)}>value+1</button>
        </div>
    )
}
デフォルトテストをエクスポート

これは React.createRef() によく似ています。上記のコード内の useRef() を React.createRef() に変更すると、同じ効果が得られます。では、なぜ新しいフックを設計するのでしょうか?用途を追加してフックの仕様を統一するだけでしょうか?
実際のところ、それらは確かに異なります。

公式サイトでは以下のように説明されています。

useRefは、.currentプロパティが渡された値に初期化された可変refオブジェクトを返します。
引数 (initialValue)。返されたオブジェクトは、コンポーネントの存続期間中ずっと保持されます。

翻訳する:

簡単に言うと、useRef はストレージ ボックスのようなものです。必要なものは何でも保存できます。再度レンダリングすると、ストレージ ボックスに移動して検索します。CreateRef はレンダリングするたびに新しい参照を返しますが、useRef は毎回同じ参照を返します。

React Hook(6つの一般的なフック)の詳細な使い方については、これで終了です。React Hookの使い方に関するその他のコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • React Hooksを使用してデータをリクエストしレンダリングする方法の詳細な説明
  • React Hooks の実装と起源、そしてそれが解決する問題の詳細な説明
  • 反応フックのユニットテスト方法
  • 完全なReact Hooksの練習を記録する
  • Webpack4とReactフックをベースにプロジェクトを構築する方法
  • React Hooksの深い理解と使用

<<:  前後の秒、分、時間、日数を取得するMySQLデータベース

>>:  Linux でネットワーク パケット損失と遅延をシミュレートする方法

推薦する

CSS3で実装された読み込みアニメーション

成果を達成する実装コード <h1>123WORDPRESS.COM</h1>...

Linuxでawkを使用する方法の詳細な説明

awk を学ぶ前に、sed、grep、tr、cut などのコマンドを学んでおく必要があります。これら...

画像の色を変更するための純粋なCSS

画像の色を変更するための CSS テクニックは非常にシンプルです。具体的なコードは次のとおりです。ヒ...

ウェブサイトのハイパーリンクを開く方法に関する議論

新しいウィンドウが開きます。 利点: ユーザーがリンクをクリックしても、現在閲覧しているコンテンツは...

Dockerプライベート倉庫の構築と利用の詳細説明

イメージは hub.docker.com に保存できますが、ネットワーク速度が比較的遅いです。内部環...

MySQL インデックスの知識の要約

MySQL インデックスの確立は、MySQL の効率的な操作にとって非常に重要です。インデックスによ...

MySQL 8.0.22 zip圧縮パッケージ版(無料インストール)のダウンロード、インストール、および構成手順の詳細

目次最初のステップはMySQLをダウンロードすることですステップ2: ダウンロードした圧縮パッケージ...

Centos での Python のアップグレードと Mongodb ドライバーのインストールに関する問題

Python バージョンを確認します (python -V)。2.7 未満の場合は、アップグレードす...

HTML の著作権記号のフォント選択問題 (著作権記号をより美しくする方法)

1. 問題を発見する&copy; は HTML の著作権記号ですが、間違ったフォントを選択す...

Navicat を使用して MySQL データベースをエクスポートおよびインポートする方法

MySql は、私たちが頻繁に使用するデータ ソースです。開発者が練習、小規模なプライベート ゲーム...

LinuxシステムでFuserコマンドを使用する方法

Fuser コマンドとは何ですか? fuser コマンドは、特定のファイル、ディレクトリ、またはソケ...

初心者向けのHTMLタグネストルールの詳細なまとめ

最近、HTML を再度学習しており、これは HTML に対する新たな理解と言えます。これを過小評価し...

JavaScript の navigator.userAgent がブラウザ情報を取得するケースの説明

ブラウザはおそらく私たちにとって最も馴染みのあるツールです。 Firefox、Opera、Safar...

CSS 境界線の長さ制御機能の実装

以前は、境界線の長さをコンテナーよりも小さくする必要があったときに、div ネストを使用していました...

ネイティブ js が携帯電話のプルダウン更新を模倣

この記事では、携帯電話のプルダウンリフレッシュを模倣したjsの具体的なコードを参考までに共有します。...