(不定期持续更新)
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计算慢