React Hookの仕組み


React Hooks
reactのhooks APIはv 16です.8から登場し、大-関数素子時代を開く.これまでクラス素子と関数素子の区別は明らかであり,関数素子は主流ではなかった.関数コンポーネントはクラスコンポーネントができるライフサイクル管理などの作業を完了していないためです.(また、正式なドキュメントには多くのクラスコンポーネントが残っています.)
しかし,クラス素子の利点と欠点は明らかである.大まかに3つにまとめることができますが、私が反応を学び始めたとき、すでに類素子の使用を避ける傾向があったので、「なるほど」と理解しました.
1.論理分離が困難
構成部品は1つの責任のみを負うことが望ましい.ロバートC.マーティンの著書『Clean Code』にこんな言葉がある."함수는 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다. 그 한 가지만을 해야 한다."オブジェクトまたは構成部品も同様です.SOLIDのSRP原則も同じことを言っているので、この構成要素もあまり変わらない.
それでも、複数の論理を含む要素が必要になる場合があるので、論理を分離することが望ましい.でもClass Componentはそれが難しいと言いました
HOCの代替案がありますが、ベストアンサーではありません.大量の包装で核心論理を把握するのが難しいからだ.
論理が分離されていないことは、論理が再利用されにくいことを意味する.同じ内容の論理が分離されないことを理由に複数回繰り返し使用すると,良いコードとは考えにくい.問題が見つかった場合は、コードを使用しているすべての構成部品を検索し、変更します.
2.壁の高さに入る.
クラス構成部品にも様々なタイプがあります.Pure Component、Presentation Componentなどの概念的な内容については、学ぶべき内容が多く、方法も多様です.廃棄される方法もあるので、よく確認して使います.
また、反応を楽に使いたい人にとって、thisの概念は高難易度にすぎない.JavaScriptがクラス概念をどのように導入するかを理解するには、thisを理解し、実行コンテキストも理解する必要があります.容易ではない.
これらの理由から,反応群はクラス素子を除いて「単純」機能のみの関数素子を発売することにした.そのため、クラスコンポーネントでしか使用できない機能も関数コンポーネントで使用しなければならない.これがhooks APIである.
ああ、関数型素子と勘違いする人も多く、「関数素子」は公式名称です.機能コンポーネントではありません.
React Hooksの動作原理
説明する前に、関数要素は関数のように理解されますが、関数自体を返さないほうが簡単です.Hookを宣言する部分、論理部分、戻り部分をそれぞれ分離し、異なるステップで素子を実現することが望ましい.
こうそくじょうけん
Hookを使用するには2つの制約があります.
  • hookは、関数コンポーネントまたはcustom hook内でのみ呼び出されます.
  • hookを呼び出す順序は常に同じでなければなりません.
  • これらの制約は空で生成されません.1番の条件は、なぜそのような制限条件があるのかを推定することができます.考えてみれば当然だ.しかし2つ目の条件は動作原理を知ってこそ理解できる.次のコードを見てみましょう.
    let hooks = [];
    
    export function useHook() {
    	// ...
    	hooks.push(hookData);
    }
    
    function processThisComponentRendering(component) {
    	component();  // 여기서 useHook()이 호출됨.
    	let hooksForThisComponent = [...hooks];
    	hooks = [];
    	// ...
    }
    
    processThisComponentRenderingは、反応器の内部で1つの要素を処理するプロセスである.この関数の内部呼び出しは、パラメータとして受信されたcomponent関数であり、このとき内部をuseHookと呼ぶ.
    useHookはuseStateであり、1つのコードで様々なhookを簡単に表現することができる.useHookの内部では、フック配列にフックの回転に必要なデータが追加される.useStateの場合、初期値はデータに入り、useEffectの場合、コールバックおよび依存配列に入る.重要なのは、Hookデータが排出されることです.すなわちjavascript interpreterは、コンポーネントコードを上から読み出し、hookを呼び出す順序で並べ替えます.ReactはこれがどんなHookなのか分からない.順番しか知らない.
    // 컴포넌트
    const Component = () => {
      const [value, setValue] = useState(0);
      
      useEffect(() => {
        console.log("hihi");
      }, [value]);
      
      return <div>Hello world</div>; 
    }
    
    
    // 위 컴포넌트를 처리한 후 hooks 배열은 아래와 같아질 것이다.(의사코드)
    [0, [() => { console.log("hihi"); }, [value]]
    
    もう一度言いますが、反応がどんなフックなのか分かりません.順番だけ覚えています.
    2番目の制約ストーリに戻ると、hook呼び出しの順序は常に同じであるべきです.簡単に言えば、条件文や重複文でhookを使用しないでください.条件文または重複文でhookを呼び出すと、hooksという低い配列エラーが発生する可能性があります.
    const Component = () => {
      if(condition()) {
        const [age, setAge] = useState(25);
      }
      
      const [name, setName] = useState('');
      
      setName('imnotmoon')  // 결과는?
      
      // ...
    }
    このようなコードがある場合、2番目の制約条件に反するコードです.
    これが危険な理由であり、condition()の戻り値に基づいて、最初のhookは呼び出しであるか、呼び出さないかのいずれかである.
    リオはフーフーの順番しか覚えていないと言った.私がsetAgeを呼んでもsetNameを呼んでも、反応は分かりません.両者を区別できる唯一の手がかりは「呼び出された順序」だけだ.しかしcondition()がfalseである場合、最初のhookは呼び出されませんが、その後のコード呼び出しsetNameは?名前を変えたいのに、年齢が変わるかもしれません.また、最悪の場合、タイプが不適切な問題でエラーが発生する可能性があります.従って、反応は第2の条件を加えた.
    Closure
    反応器がHookを実現するもう一つの核心原理はCloserである.
    // 훅이 하나 호출될 때마다 하나씩 올라감. hooks.length-1 이라고 봐도 된다.
    let idx : Number;
    let hooks = [];
    
    const Component = () => {
      
      function useState(initialValue) {
        hooks.push(initialValue);
        idx++;
        const currentIdx = idx;
    
        function setState(value) {
          hooks[currentIdx] = value;
        }
    
        return [hooks[currentIdx], setState];
      }
      
      return { useState, render }
      
    }
    関数構成部品はjsxセグメントを返します.レンダリングは、関数のライフサイクルが終了したことを意味します.それでも、useStateを戻ってきた州に近づけたり、setStateを呼んだりすることができます.これはどこかで聞いた話ではないでしょうか.モジュールはhooks APIを実現する核心原理である.
    Hook内部でもCloserを使用しています.currentIdxは、hooks配列のhookのデータが何番目にあるかを覚えています.setState関数を呼び出すとcurrentIdxにアクセスできるため、hookを使用できます.
    他のフックも同じです.レコーダを使用して、このフックに関連するデータがフック配列の数番目にあることを覚えます.
    コンポーネントの戻り部分にも関数が返されます.これにより、関数生成時のコンテキストが記憶されます.他のフックも同じです.磁気フック上のデータがフック配列の数桁に相当することをレコーダで記憶し,レコーダを核心原理として返す.この文章useStateuseEffectを直接体現し、原理を把握した.これはとてもいい文章ですから、ぜひ読んでみることをお勧めします.
    整理する
    関数要素が主流になっていますが、クラス要素に価値がないわけではありません.一部はクラスコンポーネントのみです.componentDidCatchまたはgetDerivedStateFromErrorの方法は、クラスコンポーネントにのみ存在するSuspenceおよびErrorBoundaryのコア機能を実現することである.クラス構成部品のライフサイクル管理のままで、関数構成部品が追いつかない.
    それでも関数素子は非常に良い.論理的に離れてハードルが低いので、多くの人に愛されています.私も関数要素を使ってほとんどの要素を作成します.
    反応はよくできた庫です感嘆する.