React解读史

325 阅读3分钟

(不定期持续更新)

1.为什么每个组件的js文件中,顶部都要引入 import React from 'react' ?

因为每个js文件都是一个单独的模块,需要用babel去解析,但是babel对于react jsx语法的解析实则是依赖于 React.createElement()方法,每个react组件最终默认都会去调用React.createElement()方法,如果不在顶部调用的话  会导致报错。

ex:

代码中明面上没有使用React,但是必须引入,且组件名必须首字母大写

import React, { Component } from 'react';
 
class Process extends Component {
 
  render() {
    return (<div>hello world</div>)
  }
  
}

上述代码,是我们日常开发中经常的一种写法,然而实际在编译后,我们明面上缩写的代码就会变成以下:

import React, { Component } from 'react';
 
class Process extends Component {
 
  render() {
    return React.createElement(
      'div',
      null,
      'hello world'
    );
  }
}

可以看到 最终经过babel编译之后实则是调用了React.createElement()方法来生成html元素。

jsx可以看成是js的语法糖,可以让我们在开发中更加简洁快速的进行代码编写。

而我们用jsx写出来的代码最终是要转换成浏览器认识的js语法才能很好的展示在浏览器端(ps:不用担心,babel会在你看不见的地方偷偷帮你转换),but我们要知道,从jsx到js的这个转换过程中React.createElement(),话不多说,看代码:

这是jsx的语法

<div id='one' class='two'>
    <span id="spanOne">this is spanOne</span>
    <span id="spanTwo">this is spanTwo</span>
</div>

经过转换后的js写法:

React.createElement(
  "div",
 { id: "one", class: "two" },
 React.createElement( "span", { id: "spanOne" }, "this is spanOne"), 
 React.createElement("span", { id: "spanTwo" }, "this is spanTwo")
);

React.createElement(): 根据指定的第一个参数创建一个React元素。

参数如下:

React.createElement(
  type,
  [props],
  [...children]
)
// 第一个参数是必填,传入的是似HTML标签名称,eg: ul, li// 第二个参数是选填,表示的是属性,eg: className// 第三个参数是选填, 子节点,eg: 要显示的文本内容

2.setState是同步的还是异步的???

准确的说 setState 在react合成事件中是异步的,而在setTimeout,setInterval,js原生事件中是同步的。

在React中,如果是由React引发的事件处理(比如通过onClick引发的事件处理),调用 setState 不会同步更新 this.state,除此之外的setState调用会同步执行this.state。

所谓“除此之外”,指的是绕过React,通过 addEventListener 直接添加的事件处理函数,还有通过setTimeout || setInterval 产生的异步调用。

简单一点说, 就是经过React 处理的事件是不会同步更新 this.state的. 通过 addEventListener || setTimeout/setInterval 的方式处理的则会同步更新

借用一张图来看下:


在React的setState函数实现中,会根据一个变量 isBatchingUpdates 判断是直接更新 this.state 还是放到队列 中。

isBatchingUpdates 默认是false,也就表示setState会同步更新this.state,但是有一个函数batchedUpdates

这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state。

3. dom  react原理

react 是在内存中生成并维护一个和真实dom一样的虚拟dom树,在组件改动完之后,会再生成一个新的虚拟dom,react会把新的虚拟dom和原虚拟dom进行比对,找出两个dom不同的地方diff,然后把diff放到队列里边,批量更新diff到真实dom上。

优点:最终真实dom只更新了diff部分,提高了渲染速度

缺点:首次渲染dom的时候因为多了一层虚拟dom计算,所以比html计算慢