Reactを使っていませんが、なぜ私はimportにReactを導入する必要がありますか?
5200 ワード
Reactを使っていませんが、なぜ私はimportにReactを導入する必要がありますか?
本質的にJSXは
ですから、私たちはJSXを使ったら、実はReactを使っています.だから、Reactを導入したいです.
前言
Reactは先端の一番人気のあるフレームの一つで、ソースを解読する文章がとても多いです.しかし、別の角度からReactを解読したいです.ゼロからReactを実現し、APIレベルからReactの機能の大部分を実現します.この過程で、仮想DOM、diff、なぜset Stateのようなデザインがあるのかを探ってみたいです.
Reactといえば、どうしてもVueと比べられます.
VueのAPIのデザインはとてもシンプルですが、その実現方法は「魔法」と感じられます.開発者はすぐにマスターできますが、その原理は分かりにくいです.
それに比べて、Reactの設計哲学はとても簡単で、自分で処理するべき細かい問題がたくさんありますが、新しい概念を導入していません.比較的に綺麗で簡単です.
jsxについて
始まる前に、いくつかの概念を明らかにする必要があります.
このようなコードを見てみましょう.
このコードは合法的なjsコードではありません.jsxという文法の拡張子です.これを通じて、jsコードの中でhtmlフラグメントを書くのに便利です.
本質的には、jsxは文法飴で、上記のコードはバベルから次のコードに変換されます.
React.creat ElementとバーチャルDOM
前に述べたように、jsxセグメントは
jsxから変換した結果、createElement方法のパラメータはこうです.
第1のパラメータは、DOMノードのラベル名であり、その値は
私たちはcreateElementの実現はとても簡単です.オブジェクトに戻って情報を保存すればいいです.
関数のパラメータ
今から呼んでみます.
私たちのcreateElement方法で戻ってきたオブジェクトは、このDOMノードのすべての情報を記録しています.つまり、私たちは本物のDOMを生成することができます.この記録情報の対象は仮想DOMといいます.
ReactDOM.render
次にReactDOM.render方法です.このコードを見に来ます.
したがって、
要するに、レンダー方法の役割は仮想DOMを実際のDOMにレンダリングすることであり、以下はその実現である.
レンダリングと更新
ここに来て、私たちはReactの最も基礎的な機能を実現しました.これを使って何かをすることができます.
まずindex.1にルートを追加します.
転載先:https://www.cnblogs.com/zhaohongcheng/p/11234166.html
本質的にJSXは
React.createElement(component, props, ...children)
方法のシンタックス飴です.ですから、私たちはJSXを使ったら、実はReactを使っています.だから、Reactを導入したいです.
前言
Reactは先端の一番人気のあるフレームの一つで、ソースを解読する文章がとても多いです.しかし、別の角度からReactを解読したいです.ゼロからReactを実現し、APIレベルからReactの機能の大部分を実現します.この過程で、仮想DOM、diff、なぜset Stateのようなデザインがあるのかを探ってみたいです.
Reactといえば、どうしてもVueと比べられます.
VueのAPIのデザインはとてもシンプルですが、その実現方法は「魔法」と感じられます.開発者はすぐにマスターできますが、その原理は分かりにくいです.
それに比べて、Reactの設計哲学はとても簡単で、自分で処理するべき細かい問題がたくさんありますが、新しい概念を導入していません.比較的に綺麗で簡単です.
jsxについて
始まる前に、いくつかの概念を明らかにする必要があります.
このようなコードを見てみましょう.
const title = Hello, world!;
このコードは合法的なjsコードではありません.jsxという文法の拡張子です.これを通じて、jsコードの中でhtmlフラグメントを書くのに便利です.
本質的には、jsxは文法飴で、上記のコードはバベルから次のコードに変換されます.
const title = React.createElement(
'h1',
{ className: 'title' },
'Hello, world!'
);
React.creat ElementとバーチャルDOM
前に述べたように、jsxセグメントは
React.createElement
方法で包まれたコードに変換される.したがって、第1のステップは、このReact.createElement
方法を実現するために実行される.jsxから変換した結果、createElement方法のパラメータはこうです.
createElement( tag, attrs, child1, child2, child3 );
第1のパラメータは、DOMノードのラベル名であり、その値は
div
、h1
、span
などの第2のパラメータはオブジェクトであり、中にはすべての属性が含まれており、className
、id
などを含んでいるかもしれません.第3のパラメータから開始すると、そのサブノードです.私たちはcreateElementの実現はとても簡単です.オブジェクトに戻って情報を保存すればいいです.
function createElement( tag, attrs, ...children ) {
return {
tag,
attrs,
children
}
}
関数のパラメータ
...children
は、ES 6のrestパラメータを使用しており、その役割は、後のchild 1、child 2などのパラメータを一つの配列childrenに統合することである.今から呼んでみます.
// createElement React
const React = {
createElement
}
const element = (
helloworld!
);
console.log( element );
デバッグツールを開くと、出力の対象が予想通りに見えます.私たちのcreateElement方法で戻ってきたオブジェクトは、このDOMノードのすべての情報を記録しています.つまり、私たちは本物のDOMを生成することができます.この記録情報の対象は仮想DOMといいます.
ReactDOM.render
次にReactDOM.render方法です.このコードを見に来ます.
ReactDOM.render(
Hello, world!,
document.getElementById('root')
);
変換されて、このコードはこうなりました.ReactDOM.render(
React.createElement( 'h1', null, 'Hello, world!' ),
document.getElementById('root')
);
したがって、
render
の最初のパラメータは、実際には、createElementが返したオブジェクト、すなわち、仮想DOMであり、2番目のパラメータはマウントされたターゲットDOMである.要するに、レンダー方法の役割は仮想DOMを実際のDOMにレンダリングすることであり、以下はその実現である.
function render( vnode, container ) {
// vnode ,
if ( typeof vnode === 'string' ) {
const textNode = document.createTextNode( vnode );
return container.appendChild( textNode );
}
const dom = document.createElement( vnode.tag );
if ( vnode.attrs ) {
Object.keys( vnode.attrs ).forEach( key => {
const value = vnode.attrs[ key ];
setAttribute( dom, key, value ); //
} );
}
vnode.children.forEach( child => render( child, dom ) ); //
return container.appendChild( dom ); // DOM
}
属性を設定するにはいくつかの特殊な状況を考慮して、単独で取り出して一つの方法とします.function setAttribute( dom, name, value ) {
// className, class
if ( name === 'className' ) name = 'class';
// onXXX,
if ( /on\w+/.test( name ) ) {
name = name.toLowerCase();
dom[ name ] = value || '';
// style, style
} else if ( name === 'style' ) {
if ( !value || typeof value === 'string' ) {
dom.style.cssText = value || '';
} else if ( value && typeof value === 'object' ) {
for ( let name in value ) {
// style={ width: 20 } , px
dom.style[ name ] = typeof value[ name ] === 'number' ? value[ name ] + 'px' : value[ name ];
}
}
//
} else {
if ( name in dom ) {
dom[ name ] = value || '';
}
if ( value ) {
dom.setAttribute( name, value );
} else {
dom.removeAttribute( name );
}
}
}
ここにはもう一つの小さな問題があります.render
関数を何回も呼び出した場合、元の内容はクリアされません.したがって、私たちはそれをReactDOMオブジェクトに追加する場合、まずマウント先DOMの内容をクリアします.const ReactDOM = {
render: ( vnode, container ) => {
container.innerHTML = '';
return render( vnode, container );
}
}
レンダリングと更新
ここに来て、私たちはReactの最も基礎的な機能を実現しました.これを使って何かをすることができます.
まずindex.1にルートを追加します.
我们先来试试官方文档中的Hello,World
ReactDOM.render(
Hello, world!,
document.getElementById('root')
);
結果が見られます.転載先:https://www.cnblogs.com/zhaohongcheng/p/11234166.html