深入解析React中的元素、组件、实例和节点
React 中的元素、组件、实例和节点,是React中关系密切的4个概念,也是很容易让React 初学者迷惑的4个概念。现在,我就来详细地介绍这4个概念,以及它们之间的联系和区别,满足喜欢咬文嚼字、刨根问底的同学的好奇心。 元素 (Element) React 元素其实就是一个简单JavaScript对象,一个React 元素和界面上的一部分DOM对应,描述了这部分DOM的结构及渲染效果。一般我们通过JSX语法创建React 元素,例如: const element = <h1 className=‘greeting‘>Hello,world</h1>; element是一个React 元素。在编译环节,JSX 语法会被编译成对React.createElement()的调用,从这个函数名上也可以看出,JSX语法返回的是一个React 元素。上面的例子编译后的结果为: const element = React.createElement(
‘h1‘,{className: ‘greeting‘},‘Hello,world!‘
);
最终,element的值是类似下面的一个简单JavaScript对象: const element = {
type: ‘h1‘,props: {
className: ‘greeting‘,children: ‘Hello,world‘
}//欢迎加入前端全栈开发交流圈一起学习交流:864305860
}
React 元素可以分为两类:DOM类型的元素和组件类型的元素。DOM类型的元素使用像h1、div、p等DOM节点创建React 元素,前面的例子就是一个DOM类型的元素;组件类型的元素使用React 组件创建React 元素,例如: const buttonElement = <Button color=‘red‘>OK</Button>; buttonElement就是一个组件类型的元素,它的值是: const buttonElement = {
type: ‘Button‘,props: {
color: ‘red‘,children: ‘OK‘
}//欢迎加入前端全栈开发交流圈一起学习交流:864305860
}
对于DOM类型的元素,因为和页面的DOM节点直接对应,所以React知道如何进行渲染。但是对于组件类型的元素,如buttonElement,React是无法直接知道应该把buttonElement渲染成哪种结构的页面DOM,这时就需要组件自身提供React能够识别的DOM节点信息,具体实现方式在介绍组件时会详细介绍。 组件 (Component) React 组件,应该是大家最熟悉的React中的概念。React通过组件的思想,将界面拆分成一个个可以复用的模块,每一个模块就是一个React 组件。一个React 应用由若干组件组合而成,一个复杂组件也可以由若干简单组件组合而成。 function Welcome(props) { return <h1>Hello,{props.name}</h1>; } Welcome是一个用函数定义的组件。如果使用类(class)定义组件,返回React元素的工作具体就由组件的render方法承担,例如: class Welcome extends React.Component { render() { return <h1>Hello,{this.props.name}</h1>; }//欢迎加入前端全栈开发交流圈一起学习交流:864305860 } 其实,使用类定义的组件,render方法是唯一必需的方法,其他组件的生命周期方法都只不过是为render服务而已,都不是必需的。 class Home extends React.Component { render() { return ( <div> <Welcome name=‘前端攻城小牛‘ /> <p>Anything you like</p> </div> )//欢迎加入前端全栈开发交流圈一起学习交流:864305860 } } Home 组件使用了Welcome组件,返回的React元素为: {
type: ‘div‘,props: {
children: [
{
type: ‘Welcome‘,props: {
name: ‘前端攻城小牛‘
}
},{
type: ‘p‘,props: {
children: ‘Anything you like‘
}//欢迎加入前端全栈开发交流圈一起学习交流:864305860
},
]
}
}
对于这个结构,React 知道如何渲染type = ‘div‘ 和 type = ‘p‘ 的节点,但不知道如何渲染type=‘Welcome‘的节点,当React 发现Welcome 是一个React 组件时(判断依据是Welcome首字母为大写),会根据Welcome组件返回的React 元素决定如何渲染Welcome节点。Welcome组件返回的React 元素为: {
type: ‘h1‘,props: {
children: ‘Hello,前端攻城小牛‘
}//欢迎加入前端全栈开发交流圈一起学习交流:864305860
}
这个结构中只包含DOM节点,React是知道如何渲染的。如果这个结构中还包含其他组件节点,React 会重复上面的过程,继续解析对应组件返回的React 元素,直到返回的React 元素中只包含DOM节点为止。这样的递归过程,让React 获取到页面的完整DOM结构信息,渲染的工作自然就水到渠成了。 实例 (Instance) 这里的实例特指React组件的实例。React 组件是一个函数或类,实际工作时,发挥作用的是React 组件的实例对象。只有组件实例化后,每一个组件实例才有了自己的props和state,才持有对它的DOM节点和子组件实例的引用。在传统的面向对象的开发方式中,实例化的工作是由开发者自己手动完成的,但在React中,组件的实例化工作是由React自动完成的,组件实例也是直接由React管理的。换句话说,开发者完全不必关心组件实例的创建、更新和销毁。 节点 (Node) 在使用PropTypes校验组件属性时,有这样一种类型: MyComponent.propTypes = {
optionalNode: PropTypes.node,}
PropTypes.node又是什么类型呢?这表明optionalNode是一个React 节点。React 节点是指可以被React渲染的数据类型,包括数字、字符串、React 元素,或者是一个包含这些类型数据的数组。例如: // 数字类型的节点 function MyComponent(props) { return 1; } // 字符串类型的节点 function MyComponent(props) { return ‘MyComponent‘; }//欢迎加入前端全栈开发交流圈一起学习交流:864305860 // React元素类型的节点 function MyComponent(props) { return <div>React Element</div>; } // 数组类型的节点,数组的元素只能是其他合法的React节点 function MyComponent(props) { const element = <div>React Element</div>; const arr = [1,‘MyComponent‘,element]; return arr; }//欢迎加入前端全栈开发交流圈一起学习交流:864305860 // 错误,不是合法的React节点 function MyComponent(props) { const obj = { a : 1} return obj; } 总结一下,React 元素和组件的概念最重要,也最容易混淆;React 组件实例的概念大家了解即可,几乎使用不到;React 节点有一定使用场景,但看过本文后应该也就不存在理解问题了。 结语 感谢您的观看,如有不足之处,欢迎批评指正。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |