简单的react-dom.js react.js 中的源码手写

function render(element,container){
    console.log(element)
    if(typeof element === 'string' || typeof element === 'number'){
        return container.appendChild(document.createTextNode(element))
    }
    let props,type
    type = element.type
    props = element.props
    let isReactComponent = type.isReactComponent
    console.log(type,"#####")
    if(isReactComponent){
        let componentInstance = new type(props)
        element = componentInstance.render()
    }else if(typeof type === 'function'){
        element = type(props)
    }
    type = element.type
    props = element.props
    console.log(type,"*******")
    let dom = createDOM(type,props)
    console.log(dom)
    container.appendChild(dom)
}
function createDOM(type,props){
    let dom = document.createElement(type)
    for(let propName in props){
        if(propName === 'children'){
            if(!Array.isArray(props.children)){
                render(props.children,dom)
            }else{
                props.children.forEach((child)=>render(child,dom))
            }
        }else{
            if(typeof props[propName] === 'object'){
                for(let key in props[propName]){
                    dom.style[key] = props[propName][key]
                }
            }else{
                dom.setAttribute(propName,props[propName])
            }
        }
    }
    return dom
}
export default {
    render
}
此文件为react-dom.js
class Component{
    static isReactComponent = true
    constructor(props){
        this.props = props
    }
}
function createElement(type,config = {},...children){
    let child = children
    if(child.length === 1){
        child = child[0]
    }
    let props = {...config,children:child}
    return {
        type,
        props
    }
}
export default {
    createElement,
    Component
}
此文件为react.js
 
import myReact from './handle/react';
import myReactDOM from './handle/react-dom'

// function Welcome(props){
//     return myReact.createElement('h1',{
//         className:'title',
//         style:{
//             color:'red'
//         }
//     },"hello"," ",myReact.createElement('span',null,"world"))
// }
class Welcome extends myReact.Component{
    render(){
        return myReact.createElement('h1',{
            className:'title',
            style:{
                color:'red'
            }
        },"hello"," ",myReact.createElement('span',null,"world"))
    }
}

let element = myReact.createElement(Welcome,{})
myReactDOM.render(element,document.getElementById('root'))
入口文件index.js
注意:
 
1.主要考虑ReactDOM结构和render方法里面的递归,以及目前children并不一定是数组的变化,就能很简单的写出来一个demo
2.区分函数组件还是class组件通过type.isReactComponent 静态属性来判断
3.react.js里面的createElement配合2021年1.19日的结构,children并不一定是数组,来组成数据结构
4.感想:写源码和写业务一样。
posted @ 2021-01-18 18:46  国服第一李师师  阅读(176)  评论(0编辑  收藏  举报