フロントエンドで働いている人々のほとんどは、何らかの形で反応に出くわしました。 これは、クールなインターフェースを作成するのに役立つJavaScriptライブラリーであり、最近では絶大な人気を得ています。 ただし、内部での動作を知っている人は多くありません。
この一連の記事では、コードを読んで、reactの内部にあるパッケージが何に責任を持ち、何に使用され、どのように機能するかを理解しようとします。 ブラウザで使用する最も基本的なものは、 react-dom 、 react-dom 、 eventsおよびreact-reconcilerです。
私たちは順番に移動し、今日はreactパッケージに関する記事を持っています。 このパッケージの内容を誰が気にしますか?-猫の下に行ってください。
まず、小さなパッケージを作成し、それに基づいてこのパッケージを検討します。 ガジェットは次のようになります。
function App() { const [text, changeText] = React.useState('Initial'); return ( <div className="app"> <span>{text}</span> <input type="text" value={text} onInput={(e) => changeText(e.target.value)} /> </div> ); } ReactDOM.render( <App />, document.getElementById('root') ) ;
このコードを簡単に見てみましょう。 ここでは、 React.useState('Initial')を介したフックの呼び出し、少しのJSX、およびすべてがページにReact.useState('Initial')するためのrenderメソッドの呼び出しを確認します。
実際、多くの人が知っているように、これはブラウザが処理する最終的なコードではありません。 実行される前に、たとえばダミーで変換されます。 この場合、関数が返すものは次のようになります。
return React.createElement( "div", { className: "app" }, React.createElement("span", null, text), React.createElement("input", { type: "text", value: text, onInput: function onInput(e) { return changeText(e.target.value); } }) );
誰があなたのbabelコードがbabel replに変わるかを試してみたいと思っています。
React.createElement
そのため、 React.createElement()を何度も呼び出して、この関数が何をするのかを確認しました。 言葉で説明します(または、 ReactElement.jsファイルも参照できます)。
まず、propsがあるかどうかを確認します(コードでは、渡したpropsを持つオブジェクトはconfigと呼ばれます)。
次に、 undefinedでないkeyおよびrefプロップがあるかどうかを確認し、もしあればそれらを保存します。
if (hasValidKey(config)) { key = '' + config.key; }
興味深い点は、 config.keyが文字列にconfig.keyされることです。つまり、任意のデータ型をキーとして渡すことができます。主なことは、 .toString()または.valueOf()メソッドを実装し、特定のセットに固有の値を返すことです。
次は次の手順です。
- 要素に渡された小道具をコピーします。
- propsではなく、ネストされた要素として渡した場合は、そこに
childrenフィールドを追加します。 - 以前に定義しなかったプロパティの
defaultPropsからデフォルト値を設定します。
すべてのデータを準備したら、コンポーネントを記述するオブジェクトを作成する内部関数を呼び出します。 このオブジェクトは次のようになります。
{ // This tag allows us to uniquely identify this as a React Element $$typeof: REACT_ELEMENT_TYPE, // Symbol // Built-in properties that belong on the element type: type, key: key, ref: ref, props: props, // Record the component responsible for creating this element. _owner: owner, }
ここには、シンボルである$$typeofプロパティがあります。そのため、どのオブジェクトが失敗するかはわかりません。
typeプロパティには、作成する要素のタイプが格納されます。 この例の場合、これはApp()関数と'div' 、 'span' 、および'input'ます。
keyプロパティには同じキーが含まれます。これにより、警告がコンソールに表示されます。
小道具には、渡されたもの、 children 、 defaultPropsで指定されたものが含まれます。 _ownerプロパティ_owner 、 refが正しく機能するために必要です。
例に変換すると、 React.createElement(App, null)結果はReact.createElement(App, null)ようにReact.createElement(App, null)ます。
{ $$typeof: REACT_ELEMENT_TYPE, type: App, key: null, ref: null, props: {}, _owner: null, }
さらに、開発モードでは、ファイル名と行を含む美しいスタックを表示するために使用される追加フィールドがあります。
_source: { fileName: "/Users/appleseed/react-example/src/index.js", lineNumber: 7 }

上記で見たことを要約します。 reactパッケージは、私たちとアプリケーションでさらに動作する他のパッケージとの間の翻訳者として機能し、呼び出しを、例えば調停者が理解できる単語に変換します。
React.useState
バージョン16.8では、フックが登場しました。 リンクの内容と使用方法についてはリンクを参照してください 。ただし、 reactパッケージの内容を確認します。
実際、言うことはあまりありません。 本質的に、パッケージとは、私たちの課題が内部のエンティティに通じるファサードです。
したがって、 useStateは2行のコードにすぎません。
export function useState<S>(initialState: (() => S) | S) { const dispatcher = resolveDispatcher(); return dispatcher.useState(initialState); }
残りのフックはほとんど同じように見えます。 ここで、現在のディスパッチャを取得します。これはオブジェクトであり、フィールド(たとえばuseState )を含んでいます。 このディスパッチャは、最初にレンダリングするか、コンポーネントを更新するかによって変わります。
フックの実際の実装は、 react-reconcilerパッケージに格納されています。これについては、次の記事のいずれかで説明します。
次は何ですか
もう一つ。 この記事を読んだ後、直接使用しない場合でも、常にreactパッケージをインポートする理由を理解できます。 これは、バブルでjsxを消化した後、 React変数を取得するために必要です。
反応チームのメンバーがこれを(これだけでなく)処理し、現在createElement置き換えにcreateElementます。
簡単に説明しようとすると、要素を作成する現在の方法をjsxとjsxs 2つに置き換えたいという要望がありjsxs 。 これはいくつかの理由で必要です。
- 上記で
createElement仕組みについて説明しました。 常に小道具をコピーし、 childrenフィールドをオブジェクトに追加します。このフィールドには、関数に引数として渡した子(3個以上の引数)が保存されます。 要素の作成は頻繁に呼び出される関数であり、毎回実行時に小道具の変更を自由に実行できないため、 jsxをjavascript呼び出しに変換する段階でこれを行うことが提案されています。 Reactオブジェクトのインポートを取り除き、特定の関数のみをインポートすることができます(たとえば、 import { jsx } from 'react'します)。したがって、使用していないものをアセンブリに追加できません。 さらに、 ReactオブジェクトのcreateElementフィールドもcreateElement解決するcreateElementはありません。これもフリーではないためです。key小道具から引き出してさらに転送するときに特別なケースがあることを上で説明しました。 現在、トランスパイル段階でjsxからkeyをjsxし、3番目のパラメーターを要素作成関数に渡すことが提案されていkey 。
詳細はこちら 。 reactパッケージには、すでにjsxsとjsxsます。 これを試してみたい場合は、reactリポジトリのクローンを作成し、 sharedパッケージのReactFeatureFlags.jsファイルでenableJSXTransformAPIフラグをtrueに設定し、新しいAPIを有効にして自分のバージョンのreact( yarn build )をコンパイルできます。
ファイナル
これで、 reactパッケージに関する今日の話を終わり、次回はreact-domパッケージがreactが作成するものreact 、どのメソッドとそれがどのように実装されるかを説明します。
最後まで読んでくれてありがとう!