当前位置: 首页 > 工具软件 > Element React > 使用案例 >

React Component 和 Element

单修德
2023-12-01

React 和React Element到底是什么?

React 是一个构建视图层的类库。不管React本身如何复杂,不管其他生态多么庞大,构建视图始终是他的核心。
React Element
简单的说,React Element 描述了“你想”在屏幕上看到的事物。
抽象的说,React Element 元素是一个描述了Dom Node的对象。
因为 React Element并不是你在屏幕上看见的真实事物。相反的它是一个描述真实事物的集合。

  • Javascript 对象很轻量。用对象来作为 React Element,那么React可以轻松的创建或销毁这些元素,而不必去太担心操作成本;
  • React 具有分析这些对象的能力,也就是具有分析虚拟Dom的能力。当改变出现的时候,(相比于真实Dom)更新虚拟Dom的性能优势非常明显。
    我们创建React Element的方法。
const element = React.createElement(
	'div',
	{id:'login-btn'},
	'login'
)

这里 Reac.createElement方法接收三个参数:

  • 表示标签名的字符串(div,span,etc);
  • 当前 React Element 需要具有的属性;
  • 当前 React Element要表达的内容,或者一个子元素。
    上面调用React.createElement 方法之后会返回一个 javascript 对象:
{
	type:'div',
	props:{
		children:'Login',
		id:'login-btn'
	}
}

接着当我们使用ReactDOM.render方法,这才渲染到真实的DOM上,就会得到:

<div id='login-btn'>Login</div>

React Element 深入和 React Component

我们在真正开发的时候,并不是直接使用React。createElement,而是出现了React组件,React Component。
没错,组件就是一个函数或者一个Class (当然Class 也是 function),它根据输入参数,并最终返回一个 React Element,而不需要我们直接手写无聊的React Element。

所以说,实际上我们使用了 React Component 来生成 React Element。
当然并不是所有的React Component 都需要返回 React Element ,它们还可以实现一些巧妙的设计和思想

function Buttom({onLogin}){
	return  React.createElement(
		'div',
		{id:'login-btn',onclick:onLogin},
		'Login'
	)
}

定义了一个Button组件,它接收 onLogin 参数,并返回一个 React Element 。 注意 onLogin 参数是一个函数,并最终像id:‘login-btn’ 一样成为了这个 React Element的属性。
直到目前,我们见到了React Element type为HTML标签的情况,其实我们也可以传递另一个 React Element:

const element = React.createElement(
	User,
	{name:'Lucas'},
	null
)

注意此时 React.createElement 第一个参数是拎一个 React Element ,这与type值为HTML标签的情况不相同,当 React 发现type值为一个 class 或者函数时,它就会先看这个class 换货函数会返回什么样的Element ,并为这个 Element 设置正确的属性。

React 会一直不断重复这个过程(类似于递归),知道没有createElement 调用 type 值为class 或者 function 的情况。

function Button ({addFriend}){
	return React.createElement(
		'button',
		{onClick:addFriend},
		'Add Friend'
	)
}

function User({name,addFriend}) {
	return React.createElement(
		'div',
		null,
		React.createElement('p',null,name),
		React.createElement(Button,{addFriend})
	)
}

上面有两个组件:Button 和 User , User描述的Dom是一个div标签,这个div内,又存在一个p标签,这个 p 标签展示了用户的name;还存在一个Button。
那么React.createElement的返回情况:

function Button({ addFriend }){
	return {
		type:'button',
		props:{
			onClick:addFriend,
			children:'Add Friend'
		},
	}
}
function User({name,addFriend}){
	return {
		type:'div',
		props:{
			children:[{
				type:'p',
				props:{children:name}
			},{
				type:Button,
				props:{ addFriend }
			}]
		}
	}
}

你会发现,上面的输出中,我们发现了四种type值:
button,div,p,Button

当React 发现 type 是 Button时,它会查询这个Button组件会返回什么样的 React Element,并赋予正确的 props。
直到最终,React 会得到完整的表述 Dom 树的对象。在我们的例子中,就是:

{
	type:'div',
	props:{
		children:[{
			type:'p',
			props:{children:'Tyler McGinnis'}
		},{
			type:'button',
			props:{
				onClick:addFriend,
				children:'Add Friend'
			}
		}]
	}
}

React 处理这些逻辑的过程就属于 reconciliation 的一部分,当然完整的 reconciliation更加复杂,涉及到的层面包括diff,render等,(Component到vdom,对vdom做diff,并更新到dom)
那么这个过程(reconciliation)什么时候触发呢,每次 setState 或 ReactDOM.render调用时。

JSX的角色

我们在 React Component 编写时,相信大家都在使用 JSX 来描述 Dom。当然也可以脱离 JSX 二存在,毕竟JSX是一个语法糖,不吃当然也可以。
Babel为我们做了JSX到React.createElement这件事,做了一层编译。

 类似资料: