导语
之前一直没有学习关于react技术栈有关的东西, 这次利用寒假准备春招来学习一下。
react 简介
React 是 facebook开源的javaScript库。 React把用户页面抽象成一个组件, 如按钮组件 button, 对话组件 dialog。 开发者通过组合这些组件, 最终得到功能丰富, 可交互的页面。 通过引入 JSX语法, 复用组件变得非常容易, 同时也能保证组件结构清晰。 而且有了组件这层抽象, React 把代码和真实渲染目标隔离开来, 除了可以在浏览器端渲染到 DOM 开发网页外, 还能用于开发原生移动应用。
Virtual DOM
真实页面对应一个DOM 树。 在传统页面的开发模式中, 每次需要更新页面时, 都要手动操作DOM来进行更新。
DOM操作非常昂贵。 我们都知道在前端开发中, 性能消耗最大的就是DOM操作,而且这部分代码会让项目的代码变得难易维护。 React把真实DOM树转换成 javaScript 对象树, 也就是 Virtual DOM.
每次数据更新后, 重新计算Virtual DOM, 并和上一次生成的 Virtual DOM做对比, 对发生变化的部分做批量更新。 Virtual DOM 提升了React 的性能, 但最大的好处其实还在于方便和其他平台集成。 比如 react-native是基于 Virtual DOM 渲染出原生控件, 是因为 React 组件可以映射为对应的原生控件。 在输出的时候, 是输出 WEB DOM, 还是 Android 控件, 还是 IOS控件, 就由平台本身决定了。
JSX语法
在React中通过JSX常见于的虚拟元素可以分为两类, DOM元素与组件元素, 分别对应着元素 DOM 与自定义DOM。举个例子。
1.DOM元素
我们知道, web页面是由一个个HTML元素嵌套组合而成的。 比如一个button
<button class="btn btn-blue">
<em>Confire</em>
</button>
其中包括了元素的类型和属性。如果转成了JSON对象,那么依然包括元素的类型以及属性:
{
type: 'button',
props: {
className: 'btn btn-blue',
children: [{
type: 'em',
props: {
children: 'Confirm'
}
}]
}
}
这样,我们就可以在javaScript中创建Virtual DOM元素了。
2.组件元素
当然, 我们可以很方便地封装上述 button元素, 得到一种构建按钮的公共方法。
const Button = ({ color, text }) => {
return {
type: 'button',
props: {
className: `btn btn-${color}`,
children: {
type: 'em',
props: {
children: text
}
}
}
}
}
自然,当我们要生成DOM元素中具体的按钮时,就可以方便地调用 Button({color:'blue', text:'Confirm'})来创建。
这也是React的核心思想之一。因为有公共的表达方式,我们就可以让元素彼此嵌套或混合。这就是React组件,最终我们可以用递归渲染的方式构建出完全的DOM元素树。
React组件
组件的演变
在mvvm架构出现之前,组件主要分为两种。
- UI组件, 比如Tabs组件,Dropdown组件。组件主要围绕在交互动作的抽象,针对这些交互动作,利用javaScript操作DOM结构或style样式来控制。
- 广义的组件,即带有业务含义和数据的UI组件组合。
组件的构建
React组件基本上由组件的构建方式,组件内的属性状态与生命周期方法组成。
官方React组件构建上提供了3种不同的方法:
- React.createClass
- ES6 class
- 无状态函数(stateless function)
React.createClass
用React.createClass构建组件是 React最传统,也是兼容性最好的方式。比如:
const Button = React.createClass({
getDefaultProps() {
return {
color: 'blue',
text: 'Confirm',
};
},
render() {
const { color, text } = this.props;
return (
<button className={`btn btn-${color}`}>
<em>{text}</em>
</button>
)
}
})
ES6 class
import React, { Component } from 'react';
class Button extends Component {
constructor(props) {
super(props);
}
static defaultProps = {
color: 'blue',
text: 'Confirm',
};
render() {
const { color, text } = this.props;
return (
<button className={`btn btn=${color}`}>
<em>{text}</em>
</button>
)
}
}
调用类实现的组件会创建实例对象。
说明
React的所有组件都继承自顶层类React.Component. 它的定义非常简洁,
只是初始化了React.Component方法, 声明了 props, context, refs等,
并在原型上定义了setState和 forceUpdate方法。
无状态函数
使用无状态函数构建的组件称为无状态组件,这种构建方法是官方推崇的。比如:
function Button({color = 'blue', text= 'Confirm' }) {
return (
<button className={`btn btn-${color}`}>
<em>{text}</em>
</button>
)
}
无状态组件只传入props和context两个参数; 也就是说, 它不存在 state,也没有生命周期方法,组件本身即上面两种React组件构建方法中的render方法。
在合适的情况下,我们都应该且必须使用无状态组件。无状态组件不像上述两种方法在调用时会创建新实例,它创建始终保持了一个实例,避免了检查和内存泄漏,做到了内存优化。