React Foundation Consolidation (42) - React フックの概要
1. なぜフックが必要なのでしょうか?
フックは React 16.8 の新機能であり、クラスを作成せずに状態やその他の React 機能 (ライフサイクルなど) を使用できるようにします。
クラスコンポーネント VS 機能コンポーネント:
クラスの利点:
- クラス コンポーネントは独自の状態を定義してコンポーネントの内部状態を保存できますが、関数コンポーネントは関数呼び出しごとに新しい一時変数が生成されるため、それができません。
- クラス コンポーネントには独自のライフ サイクルがあり、対応するライフ サイクルで独自のロジックを完成させることができます。たとえば、componentDidMount でネットワーク要求を送信すると、ライフサイクル関数は 1 回だけ実行されます。関数内でネットワーク リクエストを送信すると、再レンダリングのたびにネットワーク リクエストが再送信されることになります。
- クラスコンポーネントが再実行できるのは、状態が変化したときに再度呼び出したいレンダリング関数とライフサイクル関数componentDidUpdateだけであり、機能コンポーネントが再レンダリングされている間、関数全体が実行されることになり、場所がないようです一度だけ呼び出します。
クラスのデメリット:
-
コンポーネントはますます複雑になっています
- ビジネスが拡大するにつれて、クラス コンポーネントはますます複雑になります。
- たとえば、componentDidMount には、ネットワーク要求、一部のイベント監視 (componentWillUnmount で削除する必要がある) など、多くのロジック コードが含まれる場合があります。
- このようなクラスを分割するのは実際には非常に困難です。クラスのロジックは混在していることが多いため、強制的に分割すると過剰な設計が発生し、コードが複雑になります。
-
理解できないクラス
- 授業では、これが誰を指しているのかを理解する必要があるので、これを覚えるのに多くのエネルギーが必要で、非常に面倒です。
-
コンポーネントの再利用状態が困難
- 再利用可能な状態は、高レベルのコンポーネントを通過する必要があります。
- または、プロバイダーとコンシューマーと同様に、ある状態を共有しますが、コンシューマーが複数回使用されると、コードに多くのネストが含まれます。
フックの利点:
- 問題を解決します。クラスを作成せずに状態やその他の React 機能を使用します。これにより、上記の問題を解決するために多くの使用方法が拡張されます。
- 完全な互換性: 基本的に、以前にクラス コンポーネントを使用していたすべての場所を置き換えることができ、完全な下位互換性があり、段階的に使用できます。
2. クラスコンポーネントとフックを組み合わせた関数コンポーネントの比較
-
クラスコンポーネントを使用してカウンターを実装する
import React, { PureComponent } from "react"; export class CounterClass extends PureComponent { constructor(props) { super(props); this.state = { counter: 0, }; } increment() { this.setState({ counter: this.state.counter + 1, }); } decrement() { this.setState({ counter: this.state.counter - 1, }); } render() { const { counter } = this.state; return ( <div> <h2>当前计数:{ counter}</h2> <button onClick={ (e) => this.increment()}>+1</button> <button onClick={ (e) => this.decrement()}>-1</button> </div> ); } } export default CounterClass;
-
フック+関数コンポーネントでカウンターを実装する
import { memo, useState } from "react"; function CounterHook(props) { const [counter, setCounter] = useState(0); return ( <div> <h2>当前计数:{ counter}</h2> <button onClick={ (e) => setCounter(counter + 1)}>+1</button> <button onClick={ (e) => setCounter(counter - 1)}>-1</button> </div> ); } export default memo(CounterHook);
-
結果を比較する
どちらも同じ逆効果を達成できますが、上記のコード量から判断すると、フック + 関数コンポーネント方式を使用する方がコードがより簡潔で使いやすく、この関連する問題を考慮する必要がありません。これがフックによってもたらされた歴史的な変化です!