React内部メカニズム秘匿-React ComponentとElement


React内部メカニズム秘匿-React ComponentとElement
この文章は基礎に偏っていますが、入門Reactの内部メカニズムと実現原理に対しては極めて重要です.後で深く読み解くための入門です.もしあなたがすでによく知っているならば、
React Component Render=>JSX=>React.creat Element=>Virtual Dom
の流れを直接的に省略することができます.
Googleのエンジニアは問題があります.
数ヶ月前に、Googleの先端開発専門家Tyle McGininisが自身のツイッターアカウントでこのようなツイートを発表し、Reactコンポーネントについての議論を引き起こしました.
彼が投げた問題は上記のコードのように、ReactコンポーネントIconが直接コードに現れて、いったい何ですか?
提供するオプションは以下の通りです.
  • A.Component Declarationコンポーネント宣言
  • B.Component Invocationコンポーネント呼び出し
  • C.Component Instantiationコンポーネントの実装
  • D.Using a Componentは単純にコンポーネント
  • を使用します.
    面白いことに、回答に参加した開発者の中で:
  • は15%A項目を選択しました.
  • は8%がB項目を選択しました.
  • は45%C項を選択しました.
  • は32%がD項目を選択しました.
  • Reactの開発経験が豊富なフロントエンドエンジニアにとって、この問題は実によく理解されています.その鍵は、React ElementとReact ComponentsとJSXの抽象層が接続されていることがよく分かります.もちろん,いくつかの浅いReact内部動作機構も理解する必要がある.
    この文章では、このJSX抽象層の奥秘とReact Reconciliation過程を研究してみます.
    ReactとReact Elementは一体何ですか?
    最初に戻って、一番原始的な問題を考えてみましょう.Reactとは何ですか?
    簡単に言えば、
    React is a library for building user interfaces.
    Reactは、視層を構築するクラスライブラリです.React自体がどんなに複雑であっても、その生態がいかに巨大であっても、構築図は常に彼の核心である.この情報を覚えてください.今日の最初の概念であるReact Elementに入ります.
    簡単に言えば、React Elementは画面で見たいものを述べています.
    抽象的には、React Element要素は、Dom Nodeのオブジェクトを記述しています.
    React Elementはあなたが画面で見た本当のものではないので、私の言葉遣いを注意してください.反対に、彼は真実な事物を描写する集合である.存在するのは合理的で、私達はReact Elementの存在意義を見てみたいです.そしてなぜこのような概念がありますか?
  • JavaScriptオブジェクトは軽量です.対象としてReact Elementを使えば、Reactはこれらの要素を簡単に作成したり廃棄したりできます.操作コストを心配する必要はありません.
  • Reactは、これらのオブジェクトを分析する能力を持ち、さらに、仮想Domを分析する能力を有する.変化が現れると(実際のDomに比べて)仮想Domの更新の性能優位性が非常に明らかである.
  • Dom Nodeを記述するオブジェクト(またはReact Element)を作成するために、React.create Element方法を使用することができます.
    const element = React.createElement( 
      'div', 
      {id: 'login-btn'}, 
      'Login'
    )
    
    ここでReact.creat Elementの方法は三つのパラメータを受け入れます.
  • タグ名を表す文字列(div,span,etc.)
  • 現在のReact Elementの属性が必要です.
  • 現在のReact Elementが表す内容、またはサブ要素.
  • 上記のReact.creat Elementメソッドを呼び出したら、javascriptオブジェクトに戻ります.
    
    { 
      type: 'div', 
      props: { 
        children: 'Login', 
        id: 'login-btn' 
      } 
    }
    
    次に、我々はReactDOM.render方法を使用すると、これは実際のDOMにレンダリングされたとき、次のようになります.
    Login
    これこそ本当のDomノードです.
    今まで、理解しにくい概念はありませんでした.
    React Element深化とReact Component
    この記事では最初にReact Elementを紹介しましたが、公式サイトや学習資料のようにReact Componentを紹介するのではなく、React Elementを理解したと信じています.React Componentを理解するのは自然なことです.
    本当に開発する時、私達はReact.create Elementを直接使っていません.このようにするのは本当につまらないです.各部品はこのように書いたらきっと狂ってしまいます.この時、React ComponentというReactコンポーネントが現れます.
    A component is a function or a Class which optionly accepts input and returns a React element.
    そうです.コンポーネントは関数またはクラスです.入力パラメータによって最終的にReact Elementに戻ります.直接手書きでつまらないReact Elementは必要ありません.
    だから、実際にはReact Componentを使ってReact Elementを生成しました.これは開発体験の向上に大きな影響を与えました.
    ここで一つの思考問題を表します.すべてのReact ComponentはReact Elementに戻りますか?明らかに必要ではないです.それならreturn nullです.のReactコンポーネントは存在する意味がありますか?それは完成して、どれらの巧妙な設計と思想を実現することができますか?(作者に注目してください.次の文章は専門的に分析、説明します.)
    シーンの実例から問題を見る
    次に、このようなコードを見てください.
    function Button ({ onLogin }) { 
      return React.createElement( 
        'div', 
        {id: 'login-btn', onClick: onLogin}, 
        'Login' 
      )
    }
    
    私たちはButtonコンポーネントを定義し、それはonLoginパラメータを受信し、React Elementを返します.注意one Loginパラメータは関数であり、最終的にid:'login-btn'のようにこのReact Elementの属性となりました.
    今まで、React Element typeがHTMLタグ(「span」、「div」、etc)であることを見ました.実は、もう一つのReact Elementを伝えることもできます.
    const element = React.createElement(
      User, 
      {name: 'Lucas'},
      null 
    )
    
    注意この時React.creat Elementの最初のパラメータは他のReact Elementであり、これはtypeの値がHTMLタグの場合とは異なり、Reactがtypeの値が一つのクラスまたは関数であることを発見した場合、このclastまたは関数がどのようなElementに戻り、このElementに正しい属性を設定しますか?
    Reactはこのプロセスを繰り返します.「createelement呼び出しtype値がclassまたはfunction」がない場合まで.
    コードに合わせてもう一回体験します.
    function Button ({ addFriend }) {
      return React.createElement(
        "button", 
        { onClick: addFriend }, 
        "Add Friend" 
      ) 
    } 
    function User({ name, addFriend }) { 
      return React.createElement(
        "div", 
        null,
        React.createElement( "p", null, name ),
        React.createElement(Button, { addFriend })
      ) 
    }
    
    上には二つのコンポーネントがあります.ButtonとUser、User記述のDomは一つのdivタグで、このdiv内にもう一つのpタグがあります.このpタグはユーザーのnameを示しています.もう一つのButtonがあります.
    今はUserとButtonを見に来ました.React.create Elementの戻り状況:
    function Button ({ addFriend }) { 
      return { 
        type: 'button', 
        props: { 
          onClick: addFriend, 
          children: 'Add Friend' 
        } 
      } 
    } 
    function User ({ name, addFriend }) { 
      return { 
        type: 'div', 
        props: { 
          children: [{ 
            type: 'p',
            props: { children: name } 
          }, 
          { 
           type: Button, 
           props: { addFriend } 
          }]
        }
      }
    }
    
    上の出力で4つのタイプの値を見つけました.
  • 「button」
  • 「div」
  • 「p」
  • Button
  • ReactがtypeがButtonであることを発見した時、このButtonコンポーネントはどのようなReact Elementを返しますか?そして正確なpropsを与えます.
    最終的には、ReactはDomツリーを完全に表現する対象を得る.私たちの例では、
    {
      type: 'div', 
      props: {
        children: [{
          type: 'p',
          props: { children: 'Tyler McGinnis' }
        }, 
        { 
          type: 'button', 
          props: { 
            onClick: addFriend, 
            children: 'Add Friend'
          }
         }]
       } 
    }
    
    Reactがこれらのロジックを処理するプロセスをreconciliationといいますが、このプロセスはいつトリガされますか?
    答えはもちろんset StateまたはReactDOM.renderの呼び出しごとです.これからの分析文はもっと詳しく説明します.
    はい、またTylor McGinisのあの騒々しい問題に帰ります.
    この時、私たちはこの問題に答えるためのすべての知識を持っていますか?ちょっと待ってください.JSXという古い友達を引き出します.
    JSXのキャラクター
    React Componentで作成する時、皆さんはJSXを使って仮想Domを記述していると思います.もちろん、逆にReactはJSXを離れても存在します.
    冒頭の部分では、「よく言われていないJSX抽象層はどうやってReactにつながっていますか?」という答えが簡単です.JSXはいつもReact.create Elementにコンパイルされて呼び出されます.一般的にBabelは私たちのためにJSX->React.creat Elementということをしてくれました.
    先例を再確認:
    function Button ({ addFriend }) {
      return React.createElement(
        "button",
        { onClick: addFriend },
        "Add Friend" 
       )
    } 
    function User({ name, addFriend }) { 
      return React.createElement(
        "div",
        null,
        React.createElement( "p", null, name),
        React.createElement(Button, { addFriend })
      )
    }
        
    私たちがいつも書いているJSXの使い方に対応します.
    function Button ({ addFriend }) { 
      return ( 
         
      )
    }
    function User ({ name, addFriend }) {
      return ( 
        

    {name}

    ) }
    コンパイルの違いです.
    最後の答えと文末のタマゴ
    では、「Iconコンポーネントが単独で現れたら何を表していますか?」
    IconはJSXでコンパイルされた後にあります.
    React.createElement(Icon, null)
    
    
    これらのコンパイル結果はどう分かりますか?
    または
    あなたが作成したJSXが最終的にコンパイルされたのはどうなりましたか?
    私はJSXのリアルタイムコンパイルを行うためのツールを書いて、Github倉庫に置いて、このように使います.
    プラットフォームは2つに分かれています.左はJSXと書いてもいいです.右はそのコンパイル結果をリアルタイムで示しています.
    および:
    このツールの一番核心のコードは実はバベルを使ってコンパイルします.
    
    let code = e.target.value;
    try {
        this.setState({
            output: window.Babel.transform(code, {presets: ['es2015', 'react']})
            .code,
            err: ''
        })
    }
    catch(err) {
        this.setState({err: err.message})
    }
    
    興味のある読者はGitHub倉庫に行ってソースを見てください.
    締め括りをつける
    JSXであれReact Elementであれ、React Componentであれ、開発の日中に触れたものです.開発者によってはプロジェクトに慣れているかもしれませんが、その概念を深く理解していないので、Reactの核心思想を本当に把握することができません.
    これらの内容は実は基礎を比較して、しかし同時にまたとても肝心で、後でReact/Practのソースコードを理解するのに対して極めて重要です.この基礎の上で、もっと深いクラスのReactを更新して、原理分析を実現します.興味のある読者は注目してもいいです.
    他のいくつかのReact技術スタックに関する記事:
  • は、実例を通して、Reactコンポーネントを作成する「最適な実践」を学習する
  • .
  • Reactからthisを結び付けて、JS言語の発展とフレームデザインを見ます.
  • Uberモバイルのウェブページのバージョンをしますまだ十分ではない極致の性能はやっと本物の章の
  • に会います.
  • 解析Twitter先端アーキテクチャ学習複雑なシーンデータ設計
  • React Conf 2017乾物まとめ1:React+ES next=♥
  • React+Reduxが作成した「NEWS EARLY」の単一ページにプロジェクトを適用して、最前線技術スタックの真の意味を理解します.
  • react+redux工程例
  • Happy Coding
    PS:著者Github倉庫と知々応答リンクは様々な形式の交流を歓迎します.