走源码路线,浅谈react的一些思路

本文介绍如何使用create-react-app脚手架快速搭建React项目,并解析React核心概念及渲染机制。从安装Node.js环境到项目创建、启动,再到React JSX语法、createElement方法及组件渲染流程进行详细说明。

你的简单不简单,你的困难真的难

公司项目进,时间周期不够,个人感觉脚手架真的是个入门直接开发的快速选择,

搭建环境

首先需要安装node环境 略

    npm install -g creat-react-app//全局安装脚手架,任何地方都可以随时创建项目
    create reactApp//创建一个reactApp目录 并将有所依赖以及配置文件放入
    cd reactApp//进入目录
    npm start//启动项目
复制代码

你已经成功启动了一个react项目。

React主要核心库

import React from 'react';
import ReactDom from 'react-dom';

ReactDom.render(
    <h1>hello</h1>,
    document.getElementById('root')
)

复制代码

最早的版本,react和react-dom这俩个是放在一起的,后来因为各种架构的优点,互补互惠。将react-dom给拆分出来,react相当于库的核心,其他的衍生的react库都如同女朋友一样偎在他身边。可以随时更换随时使用。

这些太low了,直接讲源码,

    let objMale = <div>hello</divh1>;  等价于  React.createElement('div',null,['hello']);
    js都是可以嵌套的,react当然也可以
    let objFemale = <div>hello<span>juejin</span> 等价于 React.createElement('div',null,[React.createElement('span',null,['juejin'])]);
    console.log(objMale);
复制代码

为什么呢,这里需要一个图来解释一下,

就是这么简单(科普一下为什么外层render下面只能有一个单一根节点,并不是收到jsx的限制,而是因为每个被react渲染的元素都会是一个返回值)

    let obj = <div>hello</div>//这里最终是会return React.createElement('div',null,['hello']);
    
    如果我在 组件类中  render(){
        return (
            <div>1</div>
            <div>2</div>
        )
    }
    并不是说这不合法,而是因为走到第一个div的时候就已经直接return 出结果,不会向下继续执行。--知识点哦
复制代码

现在开始,咱们先来了解一下最简单的render方法

刚才打印出来的objMale,你会发现在控制台中展示的是一个对象,这是react特有的对象,然后type对应h1,props对应内部文本节点

let objMale = {
    type:'div',
    props:{
        children:['hello']
    }
};
//大致是这样的一个结构,这已经成为我们可以看懂的js对象了吧。

然后开始分析代码,ReactDom.render(objMale,document.getElementById('root')),这一层render做了什么事情
客观分析,定义了一个JSX Dom元素,<div>hello</div>,render只是将他给插入到页面中

简单定义一个函数 _render 名字随便起

function _render(jsxDom,container){
    //首先通过解构赋值   然后创建一个元素节点吧。
    let {type,props} = jsxDom;
    let newEle = document.createElement(type);//注意手法,这里就是将jsxDom,通过type为div 的转换成一个Dom元素
        
        <!--
            下一步操作 _nextRender (主要目的就是将props中的内容给添加到新创建的Dom元素中)
        -->
    
    //最终输出的就是讲创建的DOM元素插入到容器 -->
    container.appendChild(newEle)
}
_render(objMale,document.getElementById('root'));

//大体来说无非就是这种操作,下一步也就是把渲染的元素加上相应的文本节点,
//可以打印一下 React.createElement('div',{id:1,className:'girl'},['hello']) 这个对象看一下props
function _nextRender(newEle,props){
    //props不仅仅可能是一个对象
    for ( let attr in props){
        //介于react中的一些关键字不能和js中冲突,,jsx className  <=> class class   jsxom htmlFor <=> js for
        //这里需要加一些判断
        if(attr == 'children'){
            //这里对应上面扩展的嵌套逻辑  我的children里面也可能是个对象吧。这时候就要用到递归(知识点哦)

            props.forEach((item)=>{
                //这里只有俩种可能,一种是字符串,一种是子元素(子元素依然会和父元素的jsxDom保持一致)
                if(typeof item == 'string'){ //判断为字符串  直接添加
                    newEle.appendChild(item)
                }else{    //否则就是元素   递归,,_render(当前子元素对象,上一级创建的容器)
                    _render(item,newEle);
                }                
            })
        }else if (attr == 'className'){
            newEle.setAttribute('class',props[attr])
        }else if(attr == 'className'){
            newEle.setAttribute('for',props[attr])
        }else{
            newEle.setAttribute(attrr',props[attr])
        }
        
    }
}

let mulObj = {
    type:'div',
    props:{
        className:'ai',
        id:1,
        children:['hello',{
            type:'span',
            props:{
                className:'xi',
                id:2,
                children:['juejin']
            }
        }]
    }
};
let jsxObj = <div className="ai" id="1">hello<span className="xi" id="2">juejin</span></div>
最终渲染在页面上就都是  <div class="ai" id="1">hello<span class="xi" id="2">juejin</span></div>


_render(mulObj,document.getElementById('root')); === ReactDom.render(jsxObj,document.getElementById('root'))
并不是完全相等,只是在渲染逻辑上差不多。
复制代码
难着不会,会者不难。
跟随大神的脚步,我也一样可以天天吃鸡蛋喝牛奶

转载于:https://juejin.im/post/5ac2642af265da23793c5613

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值