Reactを使っていませんが、なぜ私はimportにReactを導入する必要がありますか?


Reactを使っていませんが、なぜ私はimportにReactを導入する必要がありますか?
本質的に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ノードのラベル名であり、その値はdivh1spanなどの第2のパラメータはオブジェクトであり、中にはすべての属性が含まれており、classNameidなどを含んでいるかもしれません.第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