React 16.8.6 学习笔记【3】【ReactDom.render() 渲染原理】

React 学习笔记 【ReactDom.render() 渲染原理】
JSX渲染机制
  • 1,通过bebel语法解析模块(babel-preset-react)把jsx语法编译为React.createElement(…);
React.createElement(
    "div",
    {
        id:"box",
        style:{color:'red',fontSize:'20px'},
        className:'title'
    },
    "\u5E74\u9F84\uFF1A"
)
  • 2,执行React.createElement(type,props,children)方法,创建一个虚拟对象(虚拟DOM)
 // 对象主要包括
 {
    key:null,
    ref:null,
    props:{
            id:"box",
            style:{color:'red',fontSize:'20px'},
            className:'title',
            children: "\u5E74\u9F84\uFF1A" //->存放的是元素中的内容,元素中的内容如果比较复杂是一个数组
        }.........
  __proto__:Object
 }
  • 3,ReactDom.render(jsx语法生成的对象,容器,回调函数),基于render方法把生成的对象动态创建DOM元素,插入到指定容器中

如下是用原生JS模拟实现render()方法

// 1,createElement
function createElement(type,props,children){
    //创建一个对象,并设置一些默认值
    let obj ={
        type:'',
        props:{children:''},
        key:null,
        ref:null
    }
    // 拓展运算,把传入进来的type和props覆盖到obj上
    obj={...obj,type,props:{...props,children}};
    // props对象中 把key和ref取出来放在外面obj中,props的key和ref删除
    if('key' in obj.props){
        obj.key =  obj.props.key;
        obj.props.key=undefined;
    }
    if('ref' in obj.props){
        obj.ref = obj.props.ref;
        obj.props.ref= undefined;
    }
 // 把重新组装的对象返回出去
    return obj
};
let jsxObj  =createElement(
                'H1',
                {
                    id:"box",
                    style:{color:'red',fontSize:'20px'},
                    className:'title',
                },
                '\u5E74\u9F84\uFF1A'
                );
                

// 2,render方法
function render(jsxObj,container,callback){
   // 解构赋值
   let {type,props} = jsxObj||{};
   // 创建dom元素
   let newEle  =document.createElement(type);
   
   // 把props的属性添加到新创建的元素上
   for(let attr in props){
   //容错处理
   // 如果不是对象的私有属性,就结束循环
   if(!props.hasOwnProperty(attr)) break;
   // 如果当前属性没有值,则跳过本次循环
   if(!props[attr]) continue;
   let value = props[attr];
   //特殊处理,className,style,children
    if( attr ==='className'){
        newEle.setAtrribute('class',value);
        continue
        };
    if(attr ==='style'){
        if(value==='') continue;
        for(let styleKey in value){
                if(value.hasOwnProperty(styleKey)){
                    newEle['style'][styleKey] = value[styleKey]
                }
            }
         continue 
        };
    if(attr ==='children'){
        if(typeof value==='string'){
          let textNode = document.createTextNode(value);
          newEle.appendChild(textNode)
        }
        continue
    }
  
     // 把遍历出来的属性和属性值设置到新创建的元素上
     newEle.setAttribute(attr,value);
   };
   
   
   
   
 //把创建的元素添加到容器中
 container.appendChild(newEle);

// 回调函数存在,就执行回调函数
callback&&callback();
}
let root = document.querySelector("#root")
render(jsxObj,root,()=>{
    console.log('渲染完毕')
})



最后在index.js中引入即可


// 自己编写的render 方法
import './self_jsx'


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值