zoukankan      html  css  js  c++  java
  • 简单的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.感想:写源码和写业务一样。
  • 相关阅读:
    Java基础(六)判断两个对象相等:equals、hashcode、toString方法
    同时找最大最小值
    0-1背包问题
    大数相加
    单例模式(singleton pattern)
    House Robber
    Binary Tree Paths
    双向链表的插入
    工厂模式(factory pattern)
    装饰者模式(decorator pattern)
  • 原文地址:https://www.cnblogs.com/MDGE/p/14294425.html
Copyright © 2011-2022 走看看