前言
React是一个用于构建用户界面的JavaScript库,起源于Facebook开发团队,据说他们对于当时市面上所有的UI库都不满意,于是自己开发了React,并作为Instagram的UI库来使用。由于发现React非常好用,于是Facebook于2013年开源了React。React设计思想属于颠覆性的创新,并且性能出众。发展至今它不再是一个简单UI库,围绕着React已经形成了一整套的行业解决方案,并受到阿里、腾讯等众多中国互联网公司的青睐,作为前端的主流框架使用。
React的特性
在之前提到React的特性我们会说:Just UI、 虚拟dom和单向数据流。这是React面世时提出的三个核心特点,随着时间的发展以及其它UI库的诞生,虚拟dom的广泛应用,并且随着React团队对于React的不断优化,现在React的三个最大特点是声明式、组件化和多端(native、node)渲染。下面我们会一一简单介绍这些特性,并会在后面的文章中详细了解。
1. JUST UI
React可以认为只是一个模板引擎,使用在任何mv*(mvc,mvvvm等)的框架中做view层,使用react的组件化思想。尽管 React 并没有假设过你的其余技术栈,但它仍可以作为一个小特征轻易地在已有项目中使用。
那么什么是MVC、什么是MVVM它们之间有什么区别,React又是怎么作为view层应用其中呢?
MVC是指Model、View、Controller的模式,而MVVM是指Modal、View、ViewModel。可以看到对于Model和View来说两种模式没有任何区别。Model一般是指数据模型,可以是数据库数据也可以是本地数据,而View就是指视图了。
在MVC模式当中controller是十分重要的一环,它负责从数据库中取出数据并处理渲染到View上,同时当用户进行交互时它也负责获取用户交互内容并处理,进而存储到数据库中,可以看出在MVC模式中,controller承担了巨大的责任。然而,随着项目越来越复杂,尤其是数据解析能力的复杂化,承担巨大责任的controller会变得越来越复杂和臃肿,使其难以维护。
这时,聪明的开发者提出了ViewModel的概念,ViewModel的主要作用就是处理数据解析,以Vue举例(由于Vue特别典型),在Vue体系中,我们可以将Vue的组件实例看做一个VueModel,将组件模板看做View,在引入Vuex等库时完全可以将model抽离出来,形成一个MVVM的模式。在Vue中,实现了一个隐式的binder,将组件实例处理好的数据和View模板进行一个双向的数据绑定。ViewModel将用户行为和视图状态的处理抽象出来,成为可复用的模块,解决了复杂数据处理下Controller的臃肿,和频繁更新dom等问题。
2.虚拟dom
虚拟dom是React提出的一个颠覆性的概念,并且作为重要的基础概念被应用在现代的各个框架之中。虚拟dom是对真实dom进行的一个抽象,将真实的dom抽象成JavaScript对象来描述。虚拟dom的的优势在于以下几点:
1. 快,通过虚拟dom,React使用了diff算法来计算出两次dom变更的最小差异,并且只渲染最小差异变化,同时React会将多次dom操作进行合并并且批量更新,从而提升性能。
2.跨端开发,虚拟dom的另一个重要的好处是实现了跨端开发,由于dom被抽象成了对象,而不是真实的节点,通过该对象我们完全可以描述我们需要渲染的内容,所以我们可以通过虚拟dom渲染native页面(ReactNative、Weex),并且还能讲虚拟dom应用在node,实现服务端渲染。
关于虚拟dom更详细的内容我们会在之后的章节进行讨论。
3.单向数据流
而在React中数据会从从顶层自上而下的通过props进行传递,复杂的交互操作时,你需要做的,只是更新你的数据源,React会把你的数据从顶层组件一层一层地传下去,React甚至会帮你优化刷新数据时对DOM节点的复用,所以你也无需关注绘制的效率问题。
关于React的数据传递我们也会在后面的文章中进行更详细的阐述。
4.声明式渲染
React 使创建交互式 UI 变得轻而易举。为你应用的每一个状态设计简洁的视图,当数据改变时 React 能有效地更新并正确地渲染组件。
与声明式对应的是命令式,简单来说,命令式是一步步的告诉电脑该怎么做,举个例子
var array = [1,2,3,4,5]
var newArray = []
for(var i = 0; i < array.length; i++) {
var newNumber = array[i] -1
newArray.push(newNumber)
}
console.log(newArray)
这是命令式的写法,而声明式的如下:
var array = [1,2,3,4,5]
var newArray = array.map(function(n) {
return n -1
})
console.log(array)
显而易见,声明式的代码思路更加清晰,更容易维护。
当进行页面渲染时,通过模板和js渲染:
<script id="test" type="text/html">
<div>
<h2>北京时间: {{ date.toLocaleTimeString() }}.</h2>
</div>
</script>
setInterval(function() {
// 数据
var data = {
date: new Date()
};
// 渲染(将数据和模板绑定在)
var html = template('test', data);
// 渲染
document.getElementById('container').innerHTML = html;
},100)
通过React声明式渲染:
class Clock extends Component {
render() {
return (
<div>
<h2>北京时间: { this.props.date.toLocaleTimeString() }</h2>
</div>
);
}
}
setInterval(function() {
// ReactDOM.render 渲染指令
ReactDOM.render(
// date 数据
<Clock date={new Date()} />,
document.getElementById('container')
);
}, 100);
很明显,通过React声明式渲染的组件思路更加清晰,且更易维护。
5. 组件化
创建拥有各自状态的组件,再由这些组件构成更加复杂的 UI。组件逻辑使用 JavaScript 编写而非模版,因此你可以轻松地在应用中传递数据,并使得状态与 DOM 分离。
可以说在React的世界中,一切皆是组件。用户的界面都是由组件拼接而成,并且组件可以组合包裹实现复杂功能,且组件可以实现副作用。
关于组件如何构建,组件的设计思想和组件的组合我们会在之后的文章中更详细的讨论。
6.一次学习,随处编写
无论你现在正在使用什么技术栈,你都可以随时引入 React 来开发新特性,而不需要重写现有代码。
React 还可以使用 Node 进行服务器渲染,或使用 React Native 开发原生移动应用。这便是虚拟dom带来的直接好处。
总结:
本文主要介绍了React的主要思想和特点:
1. React专注于View层,并可配合其它库(如Redux, Mobx等)行程MV*架构。
2. React提出了虚拟dom的概念,极大的提高了页面渲染的性能,并能在Native或服务端进行渲染。
3. 单向数据流,React的数据会从上到下的通过props传递,用户只用关心数据状态的更新。
4. React采用声明式渲染,提高代码可读性和可维护性。
5. 组件化,React中组件是一等公民。
在之后的文章中,我们会对React进行更深入的讨论。