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.感想:写源码和写业务一样。
  • 相关阅读:
    how to uninstall devkit
    asp.net中bin目录下的 dll.refresh文件
    查找2个分支的共同父节点
    Three ways to do WCF instance management
    WCF Concurrency (Single, Multiple, and Reentrant) and Throttling
    检查string是否为double
    How to hide TabPage from TabControl
    获取当前系统中的时区
    git svn cygwin_exception
    lodoop打印控制具体解释
  • 原文地址:https://www.cnblogs.com/MDGE/p/14294425.html
Copyright © 2011-2022 走看看