オープニング
現在、Reactはフロントエンド開発において最も人気のあるフレームワークの一つであり、フロントエンドにとって重要であることは自明です。今日からは数ページを使って簡単なReactフレームワークを実装し、Reactの基本的な仕組みを一緒に理解していきましょう。
React
Reactを使ったことがある子はReactのJSX構文を知っているはずですが、実はJSXはHTMLタグと同じような書き方で、パースした後、React.createElementの実際の実装は以下のようになります。
// jsx 
function render() {
 return <div>hello react</div>;
}
// 解析後、実際に実行されるのは
function render() {
 return React.createElement((type: 'div'), {}, 'hello react'); // jsオブジェクトを返す:{type: 'div',attrs: {},children: ['hello react']}
}
そこで、最初の関数であるReact.createElementのモデリングを始めます:
// Reactオブジェクトを作成し、後でそれをエクスポートする。
const React = {};
/*
 * createElement 
 * 3パラメータtype、attrs、childrenなどはすべて同じである。
 *
 */
React.createElement = function (type, attrs, ...children) {
 return {
 type,
 attrs,
 children,
 };
};
export default React;
ReactDOM
上記はReact.createElementの基本的なコアコードですが、次に別のオブジェクト--- ReactDOMを実装します:
// 後でエクスポートされるReactDOMオブジェクトを作成する。
const ReactDOM = {};
/*
 * render 
 * 2次のパラメータ:vnodeはcreateElementによって返されるオブジェクトであり、コンテナはdomノードである、例えば、ドキュメント.getELementById('app')
 *
 */
ReactDOM.render = function (vnode, container) {};
export default ReactDOM;
renderメソッドを定義し、具体的にはvnodeとcontainerというパラメータを分析し、vnodeはReact.createElementで返されるオブジェクト、containerはdomノードで、ReactDOM.renderメソッドを修正します:
// 後でエクスポートされるReactDOMオブジェクトを作成する。
const ReactDOM = {};
/*
 * render 
 * 2次のパラメータ:vnodeはcreateElementによって返されるオブジェクトであり、コンテナはdomノードである、例えば、ドキュメント.getELementById('app')
 *
 */
ReactDOM.render = function (vnode, container) {
 let element;
 // 入力されたvnodeが文字列であるかどうかを判断し、文字列である場合は、直接テキストノードを作成する。
 if (typeof vnode === 'string') {
 element = document.createTextNode(vnode);
 } else {
 // vnodeオブジェクトであれば、直接htmlノードを作成する。
 element = document.createElement(vnode.type);
 }
 // htmlにノード要素を挿入する
 container.appendChild(element);
};
export default ReactDOM;
この時点で、基本的なReactライブラリを実装することができます。
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 <title>Document</title>
 </head>
 <body>
 <div id="root"></div>
 </body>
 <!-- react.js ReactとReactDOMの両方のオブジェクトが含まれている。>
 <script src="./react.js"></script>
 <!-- index.js Reactのメソッドを導入し、実行する>
 <script src="./index.js"></script>
</html>
index.jsファイルを見てみましょう。
// JSXが解析され、React.createElement,vnodeオブジェクトを返す
const element = <div>a single react</div>;
// element実際に実行されるのは
// const element = React.createElement(type: 'div', {}, ['a single react'])
ReactDOM.render(element, document.getElementById('root'));
このhtmlファイルをブラウザで実行すると、a single reactという文字が表示されますが、これはReactが正常に実行されていることを意味します。次にindex.jsを変更します:
// JSXが解析され、React.createElement,vnodeオブジェクトを返す
// スパンの余分な層を入れ子にする
const element = (
 <div>
 <span>a single react</span>
 </div>
);
// element実際に実行されるのは
// const element = React.createElement(type: 'div', {}, [React.createElement(type: 'span',{}, ['a single react'])])
ReactDOM.render(element, document.getElementById('root'));
再帰的
ブラウザを更新すると、コンテンツがないことがわかりますが、これはなぜですか?index.jsを参照してください知っている必要があり、スパンの層よりも元の単一の反応に、そうReactDOM.renderでなければなりませんし、変更し、実行の再帰的な方法に変更すると、この問題を解決することができます:
// 後でエクスポートされるReactDOMオブジェクトを作成する。
const ReactDOM = {};
/*
 * render 
 * 2次のパラメータ:vnodeはcreateElementによって返されるオブジェクトであり、コンテナはdomノードである、例えば、ドキュメント.getELementById('app')
 *
 */
ReactDOM.render = function (vnode, container) {
 // 出口に渡されたコンテナがない場合は、フォールトトレラント判断のビットを行う
 if (!container) {
 return;
 }
 let element;
 // 入力されたvnodeが文字列であるかどうかを判断し、文字列である場合は、直接テキストノードを作成する。
 if (typeof vnode === 'string') {
 element = document.createTextNode(vnode);
 } else {
 // vnodeオブジェクトであれば、直接htmlノードを作成する。
 element = document.createElement(vnode.type);
 }
 // htmlにノード要素を挿入する
 container.appendChild(element);
 /*
 * 子があるかどうかを判断する
 * もしあれば、子を繰り返し、ReactDOMを再帰的に実行する。.render
 *
 */
 if (vnode.children && vnode.children.length) {
 vnode.children.forEach((child) => {
 /*
 * 各子で渡す
 * また、domノードとして現在の要素を渡す
 *
 */
 ReactDOM.render(child, element);
 });
 }
};
export default ReactDOM;





