初识React,Virutal DOM, State以及生命周期
这是React分类下的第一篇文章,是在了解了一些基本面后,看Tyler文章,边看边理解边写的。
React可以看做是MVC中的V,关注的是视图层。React的组件就像Angular的Directive,包括了HTML,CSS,JS以及相关数据等。React的组件被定义在了以"JSX"为后缀的文件中,这些JSX文件会被最终编译成Javascript文件。
来看一个最基本的写法:
var HelloWorld = React.createClass({
render: function(){
return (
<div>
Hello World!
</div>
)
}
});
ReactDOM.render(<HelloWorld />, document.getElementBy('app'));
以上,我们可以了解到:
- 组件创建:
React.createClass用来创建组件,接收一个object,render字段必须有 - 组件名称:就像这里的HelloWorld,通常是大写
- 组件渲染:通过
ReactDOM.render来渲染组件,该方法接收2个参数,一个参数代表组件,另一个代表渲染的位置 - 组件的呈现方式:组件是以类似HTML元素的形式呈现的,另外,如果组件中有变量,变量会以类似HTML元素属性的形式呈现
- JSX:以上的的
<div>Hello World!</div>和通常的HTML代码不一样,是放在以jsx为后缀的文件中的,最终会被转换成一个Javascript对象,最终React会创建一个"virtual DOM",React会通过React.createElement("div", null, "Hello Wolrd")创建虚拟的DOM。
1、React在"virtual DOM"这部分是如何工作的?
→ 检查数据发生变化的部分
→ 重新渲染virutal DOM
→ 与上一次的virtual DOM进行比较
→ 在实际DOM上只更新发生变化的部分
2、State
var HelloUser = React.createClass({
getInitialState: function(){
return {
username: 'firstusername'
}
},
render: function(){
return (
<div>
Hello {this.state.username}
</div>
)
}
});
- 设置组件初始状态:通过
getInitialState方法返回object对象,为state中的字段赋值 - 获取组件状态:通过
this.state.字段名来获取字段状态 - 设置组件状态:
setState虽然在上面没有提及,但这个方法时被用来真正设置组件状态的。而且这个setState方法是最常用的,当页面有数据变化,Reacct会触发setState方法,渲染virtual DOM,与上一次的virtual DOM进行比较,最后更新发生变化的部分。
2.1 通过事件改变状态
以上,是通过getInitialState方法设置了一个初始状态,如何通过事件来触发改变状态呢?比如有一个<input>,通过它的onChange方法来触发改变状态。
var HelloUser = React.creatClass({
getInitialState: function(){
return {
username: 'darren'
}
},
handleChange: function(e){
this.setState({
usename: e.target.value
});
},
render: function(){
return (
<div>
Hello {this.state.username}<br/>
Change Name:<input type="text" value={this.state.username} onChange={this.handleChange}>
</div>
)
}
});
- input的onChange事件交给了this.handleChange
- 在
handleChange方法中,通过setState改变变量的状态,接着,React渲染一个新的virtual DOM, 与上一次的virtual DOM比较差异,最后只更新发生变化的那部分DOM - React的
onChange方法用来触发事件
2.2 嵌套组件的状态传递
现在,我们知道了如何设置组件的初始状态,也知道如何如何设置组件的状态,现在来到另外一个话题:当主键有嵌套的时候,如何把父组件的状态传递给子组件呢?
先来看没有组件嵌套的情况:
var HelloUser = React.createClass({
render: function(){
return (
<div> Hello, {this.props.name}</div>
)
}
});
ReactDOM.render(<HelloUser name="darren" />, document.getElementById('app'));
- 组件在jsx语法中,是以类似页面元素的形式呈现的,比如这里的
<HelloUser />,组件中的变量,比如这里的name字段,在jsx语法中是以属性名存在的,比如这里的<HelloUser name="darren"> - 对ReactDOM来说,它知道
<HelloUser name="darren" />就是需要渲染的组件,HelloUser就是组件的名称,给name赋的值最终赋值给了props属性
再来看存在组件嵌套的情况下,如何传递State。
被嵌套的组件:
var ShowList = React.createClass({
render: function(){
var listItems = this.props.names.map(function(friend){
return <li>{{friend}}</li>;
});
return (
<div>
<h3>Friends</h3>
<ul>
{listItems}
</ul>
</div>
)
}
});
以上,ShowList组件的视图渲染需要外界给names字段赋上数组。也就是<ShowList names=... />中names属性需要赋值。从哪里赋值呢?可以从嵌套组件的state中获取。
好,那就来到嵌套组件:
var ParentContainer = React.createClass({
getIntitialState: function(){
return {
name: 'darren',
friends:['a','bob']
}
},
render: function(){
return (
<div>
<h3>Name: {this.state.name}</h3>
<ShowList names={this.state.friends}>
</div>
)
}
});
- 我们知道
getIntitialState中返回对象的各个字段是放在了state中的 - state中的friends是数组,赋值给了ShowList的names属性
- 嵌套组件和被嵌套组件之间state的传递看上去像一条河流,嵌套组件是河流的上游,被嵌套组件是下游,河水是单向流动的,上游的state向下游流动,传递给了下流的被嵌套组件
现在,组件看起来就像C#中对类的封装。React的组件是否和C#中的类有更多的相似性呢?
假设,在显示朋友列表的页面再增加一块区域,用来添加朋友信息。那,我们有必要为这一块添加的区域定义一个组件:
var AddFriend = React.createClas({
getIntialState: function(){
return {
newFriend: ''
}
},
updateNewFriend: function(e){//更新就是为state的newFriend字段赋上当前的值
this.setState({
newFriend: e.target.value
});
},
handleAddNew: function(){
this.props.addNew(this.state.newFriend);
this.setState({
newFriend: ''
});
},
render: function(){
return (
<div>
<input type="text" value={this.state.newFriend} onChange={this.updateNewFriend} />
<button onClick={this.handleAddNew}>Add Friend</button>
</div>
)
}
});
- input文本框的值取决于state中的newFriend字段值
- 为input添加了onChange事件,该事件由updateNewFriend这个代表函数的字段所定义
- 在updateNewFriend函数中,把文本框的当前值赋值给state中的newFriend字段
- 为button添加了一个onClick事件,该事件由handleAddNew所代表函数的字段所定义,而在handleAddNew函数内部,props属性需要由外界来赋值。会类似
<AddFriend addNew={...} />这样的形式呈现
以上的AddFriend组件是也是一个被嵌套组件,它和ShowList组件被一起嵌套在ParentContainer这个组件中。
于是,就来到了ParentContainer这个组件。
var ParentContainer = React.createClass({
getInitialState: function(){
return {
name: 'darren',
friends: ['a','b']
}
},
addFriend: function(friend){
this.setState({
this.setState({
friends: this.state.friends.concat([friend])
});
});
},
render: function(){
return (
<div>
<h3>Name: {this.state.name}</h3>
<AddFriend addNew={this.addFriend} />
<ShowList names={this.state.friends} />
</div>
)
}
});
被嵌套组件所需要的,都通过嵌套组件的state或函数获得。
2.3 设置组件的属性类型
在上面的AddFriend组件中,button是这样的:<button onClick={this.handleAddNew}>Add Friend</button>,button的点击事件由handleAddNew函数决定,而handleAddNew函数由this.props.addNew(this.state.newFriend)所决定,addNew函数是props属性的函数类型字段,是否可以定义呢?答案是可以。
var AddFriend = React.createClas({
getIntialState: function(){
return {
newFriend: ''
}
},
propTypes: {
addNew: React.PropTypes.func.isRequired
},
updateNewFriend: function(e){//更新就是为state的newFriend字段赋上当前的值
this.setState({
newFriend: e.target.value
});
},
handleAddNew: function(){
this.props.addNew(this.state.newFriend);
this.setState({
newFriend: ''
});
},
render: function(){
return (
<div>
<input type="text" value={this.state.newFriend} onChange={this.updateNewFriend} />
<button onClick={this.handleAddNew}>Add Friend</button>
</div>
)
}
});
3、组件的生命周期
组件的生命周期又是怎样的呢?
var FriendsConainer = React.createClass({
getInitialState: function(){
alert('getInitialState');
return {
name: 'darren'
}
},
componentWillMount: function(){},
componentDidMount: function(){},
componentWillReceiveProps: function(nextProps){},
componentWillUnmount: function(){},
render: function(){
return (
<div>
Hello, {this.state.name}
</div>
)
}
});
- componentWillMount:初次渲染之前调用一次
- componentDidMount:初次渲染之后调用,这时,可以访问virtual DOM了
- componentWillReceiveProps:初次渲染不被调用,只有当props属性值有变化才调用
- componentWillUnmount:从virutal DOM分离的时候调用
初识React,Virutal DOM, State以及生命周期的更多相关文章
- React文档(六)state和生命周期
想一下之前的章节时钟的例子. 目前为止我们只学习了一直方式去更新UI. 我们调用ReactDOM.render()方法去改变渲染的输出: function tick() { const element ...
- React Native 中组件的生命周期
概述 就像 Android 开发中的 View 一样,React Native(RN) 中的组件也有生命周期(Lifecycle).所谓生命周期,就是一个对象从开始生成到最后消亡所经历的状态,理解生命 ...
- 【react】---17新增的生命周期
一.废除的生命周期 官网文档指出使用这些生命周期的代码会在未来版本的react中更容易产生bug,尤其是对于异步渲染的版本 由于未来采用异步渲染机制,所以即将在17版本中去掉的生命周期钩子函数 com ...
- 【React 资料备份】React v16.3之后的生命周期
React v16.4 的生命周期图 React v16.4 的生命周期 变更缘由 原来(React v16.0前)的生命周期在React v16推出的Fiber之后就不合适了,因为如果要开启asyn ...
- React Native 中组件的生命周期(转)
概述 就像 Android 开发中的 View 一样,React Native(RN) 中的组件也有生命周期(Lifecycle).所谓生命周期,就是一个对象从开始生成到最后消亡所经历的状态,理解生命 ...
- 浅聊本人学习React的历程——第一篇生命周期篇
作为一个前端小白,在踏入前端程序猿行业的第三年接触了React,一直对于框架有种恐惧感,可能是对陌生事物的恐惧心里吧,导致自己一直在使用原生JS和JQ作为开发首选,但是在接触了React之后,发现了其 ...
- react native环境搭建与生命周期
1.搭建开发环境 英文文档:http://facebook.github.io/react-native/docs/getting-started.html 中文文档:https://reactnat ...
- React(四)组件生命周期
组件的生命周期可分成三个状态: Mounting:已插入真实 DOM Updating:正在被重新渲染 Unmounting:已移出真实 DOM 生命周期的方法有: componentWillMoun ...
- React对比Vue(05 生命周期的对比)
先来vue的吧,先上图,生命周期就好比一个人重出生到青少年再到青年再到中年在到老年到死亡的一个过程,不同的过程做不同的事情. 好了,上代码 beforeCreate :数据还没有挂载呢,只是一个空壳 ...
随机推荐
- Windows服务的手动添加和删除方法
Windows服务的手动添加和删除方法 服务,是指执行指定系统功能的程序.例程或进程,以便支持其他程序,尤其是低层(接近硬件)程序.其实,服务就是一种特殊的应用程序,它从服务启动开始就一直处于运行状态 ...
- Mysql基础3
一.客户管理系统CRUD二.大数据分页web页面1.MySQL:分页语句limitSELECT * FROM customer LIMIT m,n;m:代表开始记录的索引.从0开始n:一次取多少条 每 ...
- 搭建三层架构(ASP.NET MVC+EF)
昨天面试的时候最后做了一道上机题,竟然跪了,跪就跪在没有搭好框架,连接数据库总是程序报错. 回来之后亲自搭了一下框架,弄好后放到博客上.下图就是搭建好后,整个框架的结构就是这样,下面对框架中的文件进行 ...
- 关于把A表中的数据复制到B表中(整理)
如果A,B两个表中没有重复数据且表结构一样可以直接 insert into B select * from A 如果结构不一样可以 insert into B(字段列表),select 字段列表 fr ...
- Win7 64位 VS2013环境编译CGAL-4.7
看到有人在QQ空间感叹编译CGAL配置折腾了一天时间,自己也想试试,虽然并不打算用,但感觉这库也挺有名的,想必日后用得着,于是着手试着编译. 首先是看一下官网的windows下配置说明 http:// ...
- 利用Access-Control-Allow-Origin响应头解决跨域请求
//允许任何域名访问 header("Access-Control-Allow-Origin: *"); //指定域名允许跨域 header("Access-Contro ...
- coocs2d-x资源压缩笔记
使用 texturepacker 压缩: 如下设置,主要设置红框里面的,其他默认即可 上面设置的关键是 texture format 必须是 pvr.ccz,如果是png的话,下面的 img form ...
- 玩转React样式
很久很久以前,就有人用CSS来时给HTML内容添加样式.CSS可以最大限度的分离样式和内容,选择器也可以很方便的给某些元素添加样式.你根本找不到任何不用CSS的理由. 但是在React这里就是另外一回 ...
- 【转】Android 当打开“开发者模式”中的“不保留活动”后,程序应当怎么保持正常运行
当打开这个设置以后,程序的Activity会自动销毁,每次返回的时候就会不断重oncreate,此时伴随的问题多多. 参考文档:http://www.bubuko.com/infodetail-960 ...
- 设计模式UML类图基础
1.聚合 聚合(aggregation)表示一种弱的"拥有"关系,体现的是A对象可以包含B对象,但是B对象不是A对象的一部分.如大雁是群居动物,每只大雁都属于一个雁群,一个雁群可以 ...