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 でネットワーク パケット損失と遅延をシミュレートする方法

推薦する

CSS フォントの新しい使い方: カラーフォントの実装

デザイナーが特別なイベントのタイトルフォントとして以下のフォントを使用したい場合はどうすればよいでし...

CSS3+JS による虫眼鏡モードの完璧な実装の詳細説明

約 1 年前、私は「虫眼鏡効果を模倣するいくつかの方法の原理の分析」という記事を書きました。当時、自...

Windows サーバー管理におけるセキュリティの考慮事項

ウェブサーバー1. Webサーバーは、wev、cgi、asp機能を無効にするなど、不要なIISコンポ...

Vue の computed と watch の違いを分析する

目次1. 計算入門1.1、getとsetの使い方1.2. 計算された属性キャッシュ2. 時計の紹介3...

優れたウェブサイトのコピーライティングと優れたユーザーエクスペリエンス

ウェブサイトを見るというのは、実は美しい女性を評価するようなものです。見た目を見るとき、私たちは見た...

49 個の JavaScript のヒントとコツ

目次1. js整数の演算2. ネイティブアラートを書き換えてポップアップボックスの数を記録する3. ...

超大型フォントを使用した 40 の Web ページ デザイン

今日の Web デザインでは、非常に大きなフォントが表示される傾向があります。これらのオープンソース...

階段効果を実現するためのWeChatアプレットカスタムメニューナビゲーション

設計意図ページを開発する際には、ページ上のナビゲーション メニューをクリックしたときにページを対応す...

Echarts は 1 つのグラフ内で異なる X 軸を切り替える機能を実装します (サンプル コード)

レンダリング下の画像のような効果を実現したい場合は、読み続けてアニメーション画像に直接進んでください...

WeChatアプレットが9マスグリッド効果を実現

この記事では、WeChatアプレットの9マスグリッド効果を実現するための具体的なコードを参考までに紹...

制限およびオフセット ページング シナリオを使用すると速度が遅くなるのはなぜですか?

質問から始めましょう5 年前、私が Tencent にいたとき、ページング シナリオでは MySQL...

Win7 で IIS7 Web および FTP サービスを完全にアンインストールする方法

昨日、パソコンにPHP開発環境をセットアップした後、Apacheサーバーを再起動するとエラーが続きま...

Reactプロジェクトの新規作成からデプロイまでの実装例

新しいプロジェクトを始めるこの記事では主に、新規プロジェクトを0から1まで取り組むプロセスを記録し、...

MySQL のジオメトリ型を使用して経度と緯度の距離の問題を処理する方法

テーブルを作成する テーブル `map` を作成します ( `id` int(11) NULLではな...

MySQL テーブルの追加、削除、変更、クエリの基本チュートリアル

1. 作成する [テーブル名] (フィールド1、フィールド2、...) 値 (値1、値2、...) ...