0%

React.js 概念与入门

React.js 概念与入门。

介绍

什么是React

React 是Facebook开发的UI库,这个库有助于创建交互式、基于状态、可重用的UI部件。React已经应用与Facebook,Instagram全部是用React写的。

React 一个独特的地方是,它不仅可以运用与客户端,也可用于服务端,客户端和服务端可一协同操作。

React 使用了叫做Virtual DOM概念的东西,它可以根据状态的变化,有选择地渲染节点和子节点。为了更新部件,React做尽量少的DOM处理操作。

Virtual DOM如何工作?

想象你以人为模型创建了对象。这个对象具有人的属性,实时反应人当前的状态。这基本上就是React中DOM所做的。

现在想象如果你使用这个对象并做了一些改变。添加胡须,二头肌,一双英俊的眼睛。在React世界里,当你做这些改变的时候,两件事发生了。第一,React运行“辨别”算法,确定什么改变了。第二,更新DOM,确保结果和改变的一致。

React的工作方式,不是根据真实的人从头再建,它只改变对象的脸和胳膊。这意味着,如果你在文本框中输入文字,这时渲染操作开始,即使文本框的父节点没有做更新的准备,文本本身知道如何操作。

由于React使用的是虚拟的DOM,这也就产生了另一种有趣的可能。我们可以在服务端渲染虚拟的DOM,快速更新React视图。

开始

使用React,首先要安装React CLI工具(用以创建React应用),运行以下命令创建新应用:

1
2
3
4
5
6
7
# 安装 CLI 工具
npm install -g create-react-app
# 创建应用
create-react-app my-app-name
# 安装依赖包
cd my-app-name
npm install

页面设置

设置页面的时候,你需要引入react.jsreact-dom.js及Babel编译器脚本。然后在type设置为text/babel的脚本区域写部件(component):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@latest/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@latest/dist/react-dom.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<div id="myDiv"></div>
<script type="text/babel">

<!-- React Code Goes Here -->

</script>
</body>
</html>

React中,部件(component)加载到元素(element)上,所以在这个例子中,我们使用myDiv作为它的父容器。

虽然这个开始方式很容易,在创建实际项目的时候,一般使用Browserify或者Webpack来将部件放置到不同的文件中。

基础

React是以部件为基础的,我们写一个:

1
2
3
4
5
6
7
<script type="text/jsx">
/** @jsx React.DOM */
React.render(
<h1>Hello, world!</h1>,
document.getElementById('myDiv')
);
</script>

如果这样的代码是你第一次看到,你会有点疑惑:这段代码里隐含了Javascript/HTML的什么魔法?

JSX

它叫做JSX,是Javascript XML语法的变种,使你在脚本中写类似HTML标记。为了与Javascript保留关键字区别,对于一些常规的html标记,在JSX中classclassNameforhtmlFor。如果不使用JSX,上述的代码是这样的:

1
2
3
4
5
6

/** @jsx React.DOM */
React.render(
React.DOM.h1(null, 'Hello, world!'),
document.getElementById('myDiv')
);

部件(components)

在上面代码使用render方法的时候,我们第一个参数是我们要渲染的部件,第二个参数是部件要挂载的DOM节点。我们可以使用createClass方法创建部件类,在创建参数中对对象配置:

1
2
3
4
5
6
7
var MyComponent = React.createClass({
render: function(){
return (
<h1>Hello, world!</h1>
);
}
});

创建类之后,我们可以在文档中渲染它:
1
2
3
4
React.render(
<MyComponent/>,
document.getElementById('myDiv')
);

属性(Props)

定义我们的部件时,我们可以为部件定义属性。这些属性在部件中表示为this.props,在渲染方法中能够动态显示数据:

1
2
3
4
5
6
7
8
9
var MyComponent = React.createClass({
render: function(){
return (
<h1>Hello, {this.props.name}!</h1>
);
}
});

React.render(<MyComponent name="Handsome" />, document.getElementById('myDiv'));

部件生命周期和状态

创建部件我们只需要render方法即可,实际如果你想要部件发挥作用,我们有时需要部件的生命周期方法。

生命周期方法

以下的生命周期方法你应该了解:

  • componentWillMount 激活一次,在客户端&服务端渲染发生之前
  • componentDidMount 激活一次,在客户端发生渲染之后
  • shouldComponentUpdate 返回部件是否更新
  • componentWillUnmount 在部件卸载之前激活

生命周期方法中的函数

  • getInitialState 返回状态的初始化值
  • getDefaultProps 如果属性没有提供,设置回调属性值
  • mixins 对象数组,用以扩展当前部件的功能

状态

每个部件都既有状态state也有属性props,设置状态用setState方法。调用setState会触发UI更新。如果我们想在交互之前初始化部件状态,可以用getInitialState。下面,我们设置部件的状态:

1
2
3
4
5
6
7
8
9
10
11
12
var MyComponent = React.createClass({
getInitialState: function(){
return {
count: 5
}
},
render: function(){
return (
<h1>{this.state.count}</h1>
)
}
});

事件(Events)

React中,事件作为属性绑定到部件上,可以触发方法。我们用事件来实现计数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var Counter = React.createClass({
incrementCount: function(){
this.setState({
count: this.state.count + 1
});
},
getInitialState: function(){
return {
count: 0
}
},
render: function(){
return (
<div class="my-component">
<h1>Count: {this.state.count}</h1>
<button type="button" onClick={this.incrementCount}>Increment</button>
</div>
);
}
});

React.render(<Counter/>, document.getElementById('myDiv'));

上面的代码演示在这儿

单向数据流

React中,应用数据流经过stateprops单向流动。这意味着,在多层级部件页面中,父部件负责管理状态并向下传递。

更新状态使用setState方法以确保UI的刷新。结果值应该以子部件属性this.props向下传递。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/** @jsx React.DOM */

var FilteredList = React.createClass({
filterList: function(event){
var updatedList = this.state.initialItems;
updatedList = updatedList.filter(function(item){
return item.toLowerCase().search(
event.target.value.toLowerCase()) !== -1;
});
this.setState({items: updatedList});
},
getInitialState: function(){
return {
initialItems: [
"Apples",
"Broccoli",
"Chicken",
"Duck",
"Eggs",
"Fish",
"Granola",
"Hash Browns"
],
items: []
}
},
componentWillMount: function(){
this.setState({items: this.state.initialItems})
},
render: function(){
return (
<div className="filter-list">
<input type="text" placeholder="Search" onChange={this.filterList}/>
<List items={this.state.items}/>
</div>
);
}
});

var List = React.createClass({
render: function(){
return (
<ul>
{
this.props.items.map(function(item) {
return <li key={item}>{item}</li>
})
}
</ul>
)
}
});

React.render(<FilteredList/>, document.getElementById('myDiv'));

上面的示例代码在这儿

结论

上面介绍的是React基础只是,如需进一步了解,可以阅读React APIJSX

以上内容来自于Learning React.js: Getting Started and Concepts