一、简介
React是Facebook在2013年开源在GitHub上的JavaScript库。
React把用户界面抽象成一个组件,如按钮组件Button、对话框组件Dialog、日期组件Calendar。开发者通过组合这些组件,最终得到功能丰富、可交互的页面。通过引入JSX语法,复用组件变得非常容易,同时也能保证组件结构清晰。
通过组件这层抽象,React把代码和真实渲染目标隔离开来,除了可以在浏览器端渲染到DOM来开发网页外,还能用于开发原生移动应用。
特点:
- 提供View层解决方案,包括View和Controller的库
- 使用Virtual DOM保证性能
- 函数式编程
这里需要了解什么是Virtual DOM
Virtual DOM
每个真实页面对应一个DOM树。在传统页面的开发模式中,每次需要更新页面时,都需要手动操作DOM来进行更新(jQuery),如图所示:

在前端开发中,性能消耗最大的就是DOM操作,而且这部分代码会让整体项目的代码变变得难以维护。React把真实DOM树转换为JavaScript对象树,也叫Virtual DOM,如图所示:

每次数据更新后,重新计算Virtual DOM,并和上一次生成的Virtual DOM作对比,对发生变化的部分做批量更新,以保证性能
Virtual DOM最大的好处其实还在于方便和其它平台集成,比如react-native是基于Virtual DOM 渲染出原生控件,因为 React组件可以映射为对应的原生控件。在输出的时候,是输出Web DOM,还是Android控件,还是iOS控件,就由平台本身决定了。因此,react-native 有一个口号——Learn Once,Write Anywher
二、JSX语法
React不同于传统的模板引擎,它包括View和Controller,为方便View层组件化,承载了构建 HTML 结构化页面的职责。从这点上来看,React 与其他JavaScript模板语言有着许多异曲同工之处,不同之处在于React是通过创建与更新新虚拟元素(virtual element)来管理整个Virtual DOM的。
其中,虚拟元素可以理解为真实元素的对应,它的构建与更新都是在内存中完成的,并不会真正渲染到DOM中去。在React中创建的虚拟元素可以分为两类,DOM元素(DOM element)与组件元素(component element),分别对应原生DOM元素与自定义元素,而JSX与创建元素的过程有莫大的关系。

JSX是一个语法糖,作用是将HTML语法直接加入到JavaScript代码中,再通过编译器转换到纯JavaScript后由浏览器执行。常用的编译器有babel。
1. XML基本语法
-
定义标签时,只允许被一个标签包裹。例如
const component = <span>name</span><span>value</span>
这样写会报错。原因是一个标签会被转译成对应的React.createElement调用方法,最外层没有被包裹,无法转译成发放调用 -
标签一定要闭合,否则无法通过编译
2. 元素类型
DOM元素和组件元素,HTML标签首字母为大写字母对应JSX中的组件元素,小字母对应JSX中的DOM元素
const Title = (children) => (
<h3>{children}</h3>
);
const List = () => (
<div>
<Title>This is title</Title>
<ul>
<li>list item</li>
<li>list item</li>
<li>list item</li>
</ul>
</div>
);
如上图中,div标签会生成DOM元素,Titile会生成组件元素
3. 元素属性
在JSX中DOM元素属性是标准规范属性,除了class和for,因为在JavaScript中这两个是关键词,因此
- class改为className
- for改为htmlFor
组件元素的属性是完全自定义的
const Header = ({title, children}) => (
<h3 title={title}>{children}</h3>
);
调用时
<Header title="hello world">Hello world</Header>
Boolean属性
省略Boolean属性值会导致JSX认为bool值设置为了true。要传false时,必须使用属性表达式。这常用于表单元素中,比如 disabled、required、checked 和 readOnly 等。
例如,<Checkbox checked={true} />
可以简写为<Checkbox checked />
,反之<Checkbox checked={false} />
就可以省略checked属性。
展开属性
如果事先知道组件需要的全部属性,JSX 可以这样来写:
const data = { name: 'foo', value: 'bar' };
const component = <Component name={data.name} value={data.value} />
这里,可以使用 ES6 rest/spread 的特性提高效率:
const data = { name: 'foo', value: 'bar' };
const component = <Component {...data} />;
自定义HTML属性
如果在 JSX 中往 DOM 元素中传入自定义属性,React 是不会渲染的:
<div d="xxx">content</div>
如果要使用 HTML 自定义属性,要使用 data- 前缀,这与 HTML 标准也是一致的:
<div data-attr="xxx">content</div>
在自定义标签中,任意的属性都是被支持的
JavaScript属性表达式
属性值要使用表达式,只要用{}来替换""
// 输入(JSX):
const person = <Person name={window.isLoggedIn ? window.name : ''} />;
// 输出(JavaScript):
const person = React.createElement(
Person,
{name: window.isLoggedIn ? window.name : ''}
);
HTML转义
React 提供了 dangerouslySetInnerHTML 属性,它的作用就是避免React转义字符
参考:
《深入React技术栈》 陈屹峰著
网友评论