フロントエンドで働いている人々のほとんどは、何らかの形で反応に出くわしました。 これは、クールなインターフェースを作成するのに役立つ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
、どのメソッドとそれがどのように実装されるかを説明します。
最後まで読んでくれてありがとう!