首先介紹jsx語法 , 其實jsx= javascript + xml,看上去是html其實不是.javascript
let element = <h1 id='myid'>hello world</h1>
經過bable 轉義後變成html
let element= React.createElement('h1',{id:'myid'},'hello world') //這裏咱們稱React元素,這是React最小單位
寫完React元素,就能夠render渲染,就能夠在頁面中呈現了.java
ReactDom.render(element,document.getELementById('root'))
如圖這個就是咱們要的react元素
react
function createElement(type,config={},children){ let props={}; for(let propsName in config){ props[propsName]=config[propsName] }; let childrenLength = arguments.length-2; if(childrenLength==1){ props.children=children }else if( childrenLength >1){ props.children=Array.from(arguments).slice(2) } let element={type,props} return element }
思路:數組
render函數是把React元素(虛擬dom)渲染成htmlapp
function render(element,parentNode){ if(typeof element == 'string' || typeof element =='number'){ return parentNode.appendChild(document.createTextNode(element)) } let {type,props}=element; let domElement = document.createElement(type); for(let propsName in props){ switch(propsName){ case propsName=='className': return domElement.className=props[propsName]; case propsName=='style': let styobj= props[propsName] for(let attr in styobj){ domElement.style[attr]=styobj[attr] } return case propsName=='children': let children = Array.isArray(props.children)?props.children:[props.children] children.forEach(element=>{ render(element,domElement) }) return default: domElement.setAttribute(propsName,props[propsName]) } } parentNode.appendChild(domElement) }
思路:dom
render函數2個參數分別爲react元素,根組件,咱們先判斷react元素是否是string和number由於能夠直接渲染好比像這樣函數
ReactDom.render('abc',document.getElementById('root'))
function Welcome(props){ return React.createElement('h1',{id:'zhufeng'},props.name,props.age) } ReactDOM.render(element, document.getElementById('root'));
咱們得在render裏面去添加邏輯,只須要把這個函數執行後就可,由於它的返回值仍是咱們的react元素.this
function render(element,parentNode){ if(typeof element == 'string' || typeof element =='number'){ return parentNode.appendChild(document.createTextNode(element)) } let {type,props}=element + if(typeof type == 'function'){ + let newElemet=type(props) + type=newElemet.type; + props=newElemet.props; } //如下邏輯相同 }
class Welcome1 extends React.Components{ render(){ return React.createElement('h1',{id:'classwelcome'},this.props.name,this.props.age) } }
一樣的思路,咱們先去建立一個Components組件讓它去繼承.spa
class Components{ static isReactComponents=true constructor(props){ this.props=props } }
這個組件咱們只須要去傳遞props讓子組件去繼承就能夠,另外isReactComponents這個靜態屬性是用來標識是不是類組件.
接下來咱們繼續改render函數
function render(element,parentNode){ if(typeof element == 'string' || typeof element =='number'){ return parentNode.appendChild(document.createTextNode(element)) } let {type,props}=element + if(type.isReactComponents){ + let newElemet=new type(props).render() + type=newElemet.type; + props=newElemet.props; + }else if(typeof type == 'function'){ + let newElemet=type(props) + type=newElemet.type; + props=newElemet.props; + } } //如下邏輯相同 }
那麼咱們就能夠順利跑通啦.