React :元素构成组件,组件又构成应用。
React 元素就是 普通的js对象
(俗称:虚拟DOM)
。
React 元素不是真实的 DOM 元素,所以也没办法直接调用 DOM 上原生的 API。
渲染过程:
React元素 描述 虚拟DOM,再根据 虚拟DOM 渲染出 真实DOM。
1、虚拟 DOM :就是用 js 对象结构模拟出 html 中 dom 结构,批量的增删改查先直接操作 js 对象,最后更新到真正的 DOM 树上。因为直接操作 js 对象的速度要比操作 DOM 的那些 api 要快。
2、React 元素就是js对象
,它用来告诉 React,你希望哪些东西显示在页面中。
总的说:
元素就是用来描述 DOM 节点或者 React 组件的纯对象。元素可以在自己的属性中包含其它元素。创建一个元素的成本很低,一旦元素被创建之后,就不再发生变化。
例如:我们可以使用 JSX 语法,创建一个 React 元素 element:
const element = <h1 className='greeting'>Hello, worldh1>;
在编译过程中,JSX会被编译成对React.createElement()的调用,从这个函数名上也可以看出,JSX语法返回的是一个React 元素。
上面的例子编译后的结果为:
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
最终,element的值被编译为是类似下面 的js对象:
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world'
},
_context: Object,
_owner: null,
key: null,
ref: null,
}
1、使用 JSX 语法
const element = <h1>Hello, worldh1>;
2、React.createElement()
它接受三个参数:
React.createElement(
type,
[props],
[...children]
)
JSX 语法就是用React.createElement()来构建 React 元素的。
3、React.cloneElement()
React.cloneElement()与React.createElement()相似,不同的是它传入的第一个参数是一个 React 元素,而不是标签名或组件。
新添加的属性会并入原有属性,同属性名新的会替换旧的,传入到返回的新元素中。
React.cloneElement(
element,
[props],
[...children]
)
eg:
let element = "myid">dadad
;
let element2 = React.cloneElement(
element,
{className:'myclass',id:'myid2'},
'哈哈哈哈'
);
ReactDOM.render(element2,document.getElementById('root'));
输出:哈哈哈哈
我们查看下此时被编译后的html,我们发现id,class属性合并,且子节点被替换。
<h1 id="myid2" class="myclass">哈哈哈哈h1>
我们要渲染一个 React 元素到一个 root DOM 节点,需要把它们传递给 ReactDOM.render()
方法:
例1、
<div id="root">div>
const element = Hello, world
;
ReactDOM.render(
element,
document.getElementById('root')
);
输出:Hello, world
例2、
<div id="root">div>
<script type="text/babel">
var child1 = React.createElement('li', null, 'First Text Content');
var child2 = React.createElement('li', null, 'Second Text Content');
var child3 = React.createElement('li', null, 'Third Text Content');
var root = React.createElement('ul', { className: 'my-list' }, child1, child2, child3);
//可以认为第三个参数是一个数组,数组中的元素就是该节点的所有子节点。
//所以还可以为 var root = React.createElement('ul', { className: 'my-list' }, [child1, child2, child3]);
ReactDOM.render(
root,
document.getElementById('root')
);
script>
React 元素是 不可变
的. 一旦你创建了一个元素, 就不能再修改其子元素或任何属性。
更新 UI 的唯一方法是创建一个新的元素, 并将其传入 ReactDOM.render() 方法.
<div id="root">div>
<script type="text/babel">
function tick() {
const element = (
<div>
<h1>Hello, world!h1>
<h2>It is {new Date().toLocaleTimeString()}.h2>
div>
);
ReactDOM.render(
element,
document.getElementById('root')
);
}
setInterval(tick, 1000);
script>
React 只更新必需要更新的部分。
React DOM 会将元素及其子元素与之前版本逐一对比, 并只对有必要更新的 DOM 进行更新, 以达到 DOM 所需的状态。
(React判断DOM是否变化的方式很暴力:遍历所有DOM节点,一边遍历一边判断DOM前后是否相等
) 这里涉及到diff算法,我们暂时不做解释。
我们可以拿上面例子说事:
即使我们我们每隔 1 秒都重建了整个元素, 但实际上 React DOM 只更新了修改过的文本节点.