React.js再探(三)

很多时候,组件实例的外观和行为我们通过props进行定制就可以了。因为任何时候,组件实例的表现只跟 传过来的props属性 相关。

我们称这种为 无状态/ stateless 组件

即它自身是 无记忆的

比如切换开关,它可以响应用户的点击事件,如果当前状态是关,那么它就 切换到开的状态(显示开状态的图片);而如果当前状态是开,那么它就切换到关的 状态(显示关状态的图片)

状态记忆:state

React引入了状态机的概念,让组件具有不同的状态,使得组件具有记忆功能

具体如下:

  • state ——组件的状态

每个组件都有一个state变量,保存组件的当前状态。用this.state可以获取到组件的当前状态。

  • getInitialState()——设置组件初始状态

开发者应当写一个getInitialState() 方法来设置组件的初始状态。该方法必须返回一个JSON对象或者空值null。

  • setState(currentState)——设置当前组件状态

currentState必须是一个JSON对象,但只需要写上需要设置的状态的键值对,不必把所有状态变量都包含。

我们虽然可以对this.state进行赋值来设置当前组件的状态。但是React官方推荐使用setState(),因为用该方法会自动重新渲染组件。当前如果有特殊需求,是可以用this.state的。

具体运用如下面这个开关的例子:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="utf-8">
 5     <title>EzSwitchComp</title>
 6     <script src="lib/react.min.js"></script>
 7     <script src="lib/JSXTransformer.js"></script>
 8 </head>
 9 <body>
10     <div id="content"></div>
11     <script type="text/jsx">
12         //组件定义
13         var EzSwitchComp = React.createClass({
14             //设置初始状态
15             getInitialState : function(){
16                 return {on : false};
17             },
18             //处理点击事件,切换状态
19             onClick : function(){
20                 //读取并重设状态,这将触发重新渲染
21                 this.setState({on : !this.state.on});
22             },
23             render : function(){
24                 //根据状态设置样式
25                 img = this.state.on ? "img/switch-on.png" : img = "img/switch-off.png";
26
27                 //返回元素
28                 return <img src = {img} style={{width:"150px"}} onClick={this.onClick}/>;
29             }
30         });
31         //渲染
32         React.render(
33             <EzSwitchComp/>,
34             document.querySelector("#content"));
35     </script>
36 </body>
37 </html>

我们这里加一个需求,开关只有4次的寿命,即只能切换4次,之后alert出坏了。

下面我们就来实现,首先既然要保存寿命这个变量,让组件有记忆功能,那么就是继续使用state

直接上代码吧

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="utf-8">
 5     <title>EzSwitchComp</title>
 6     <script src="lib/react.min.js"></script>
 7     <script src="lib/JSXTransformer.js"></script>
 8 </head>
 9 <body>
10     <div id="content"></div>
11     <script type="text/jsx">
12         //组件定义
13         var EzSwitchComp = React.createClass({
14             //设置初始状态
15             getInitialState : function(){
16                 return {
17                          on : false,
18                          life: 4
19                 };
20             },
21             //处理点击事件,切换状态
22             onClick : function(){
23                 if(!!this.state.life)
24                   //读取并重设状态,这将触发重新渲染
25                   this.setState({"on" : !this.state.on,"life": --this.state.life });
26                 else
27                   alert(‘已完‘);
28             },
29             render : function(){
30                 //根据状态设置样式
31                 img = this.state.on ? "img/switch-on.png" : img = "img/switch-off.png";
32
33                 //返回元素
34                 return <img src = {img} style={{width:"150px"}} onClick={this.onClick}/>;
35             }
36         });
37         //渲染
38         React.render(
39             <EzSwitchComp/>,
40             document.querySelector("#content"));
41     </script>
42 </body>
43 </html>

这里不小心犯了一个小错误,就是this.setState({"on" : !this.state.on,"life": --this.state.life });

这句话,之前写了是 life:this.state.life--   ,然后发现console出来的this.state.life一直是4,至于这里的错误的原因,相信看官想想就明白了,就不多说了。

生命周期

熟悉WebComponent的同学应该都知道,组件是有生命周期的,在WebComponent中,就有4个生命周期的回调函数。

在React中,生命周期的回调函数分的更细

componentWillMount()——组件实例即将初次渲染时调用,整个周期中只调用1次

componentDidMount()——组件实例初次渲染后调用,只调用1次

componentWillReceiveProps(nextProps)——组件实例即将设置新属性时调用,nextProps表示新属性值。在此方法内调用setState()不会引起重新渲染。(不知道这个有什么特别的用法)

shouldComponentUpdate(nextProps, nextState)——组件实例即将重新渲染时调用。此方法返回false时,组件实例不会被渲染,true则渲染。通过forceUpdate()方法进行重新渲染时,这个方法不会被调用。

componentWillUpdate(nextProps, nextState)——组件实例即将重新渲染时调用。不能在此方法内调用setState()

componentDidUpdate(prevProps, prevState)——组件实例重新渲染后调用

componentWillUnmount()——组件实例即将从DOM树中移除时调用,只调用1次

好了,今天先这样,明天继续.....

时间: 2024-12-15 06:55:44

React.js再探(三)的相关文章

React.js再探(二)

上文中说到了组件了. 我们使用组件的目的最大莫过于复用,提供生产效率. 那么,这时候组件就应该能够提供一些”api”出来,让开发者去定义在不同场景下的不同表现,比如,行为或外观等. 而这些“api”就是 属性   在React中,用 props 访问实例元素的属性 属性:props 比如在JSX片段中,组件的实例元素有一个属性onoff: 1 React.render( 2 <ezlampcomp onoff="off"></ezlampcomp> , 3 do

React.js再探(四)

不知道看官们还记不记得上一节的内容,关于生命周期的.我们来个例子重温且练习一下. 传送门:http://www.cnblogs.com/galenyip/p/4574400.html 我们来实现一下时钟的功能,要求当秒是“0”的时候,字体变为红色.注意用componentWillUpdate实现. 如       当秒是0   变为 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8&qu

React.js 基础入门三 ---组件状态state

React 组件实例在渲染的时候创建.这些实例在接下来的渲染中被重复使用,可以在组件方法中通过 this 访问.唯一一种在 React 之外获取 React 组件实例句柄的方式就是保存React.render 的返回值.在其它组件内,可以使用 refs 得到相同的结果(后面会简单解释refs). 从上几章的学习,我们可以这么理解组件,学过php的Yii框架的都知道widget组件,react.js定义一个组件,通过在组件中定义各种'方法','属性'最后通过render来渲染这个组件. 其中<组建

React.js终探(七)(完)

我们在前面介绍了组件的各种特性,这一节我们来说说多组件的情况. 在实际开发中,我们的组件难免会遇到有公共部分的情况,如果是个别情况还好,但如果数量比较多的话,那这时候,就需要公用了. 怎么公用呢? React为我们提供了它的方法. mixin:复用代码 可以把部分代码提出来公用.mixin是掺合混合的意思,即可以把一个对象的属性拷贝到另一个对象上. 使用mixin有两步: 定义一个mixin对象,即如 1 var EzLoggerMixin = { 2 log:function(){ 3 //s

react.js 从零开始(三)JSX 语法及特点介绍

什么是jsx? jsx = JavaScript + xml jsx 是一种 Ecmascript 的一种新标准. jsx 是一种 带有结构性的语法. jsx 的特点: 1.类xml语法易于理解. 2.增强js语意. 3.结构清晰. 4.抽象程度高,易于跨平台. 5.代码模块化. 如何使用jsx? var style={color:"red"}; var HolleWorld = React.createClass({ render: function() { return <p

React.js终探(五)

在React中,一切都是看做组件. 而组件的嵌套也是十分常见的. 所以有的组件就作为容器组件 容器组件 React元素可以包含子元素 如 1 //JSX 2 <ezpanel title="title"> 3 <p>this is demo content</p> 4 </ezpanel> 在React中,用this.props.children可以访问子元素 如: 1 var EzPanel = React.createClass({

再谈React.js实现原生js拖拽效果

前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目地就是要尽量避免直接操作dom元素,所以我们在对dom元素进行操作的时候需要注意,我之前为了获取form的参数就直接用了var dragBox=document.getElementById('form')去找dom,但是其实记录from的初始位置,可以在其子组件更新父组件参数的时候调用.即在MyF

再探 butterfly.js - grunt.js篇(一)

再探 butterfly.js - grunt.js篇(一) 神器 grunt.js 久仰grunt.js的大名,学习grunt.js一直是我todo List的第一位.趁着新春佳节来临之际(打酱油的日子),就来填了这个坑,完了这个心愿. grunt.js的强大,强大在于它拥有很多用途丰富的插件,和不同插件之间的联动实现更牛逼的功能. 这里默认大家已经安装了npm和会用npm install等指令,就不详细讲了.下面讲用到grunt-contrib-watch和grunt-contrib-con

再探 butterfly.js - 奇异的留白

再探 butterfly.js - 奇异的留白 事情经过 在 梓凡兄 捣鼓他的 豆瓣FM 播放器的时候,发现了butterfly.js会在ipad的横屏模式(landscape mode)的时候对<html>添加class="ipad ios7".更加离奇的是在butterfly.css有以下样式: @media (orientation:landscape){ html.ipad.ios7 > body{ position:fixed;bottom:0;width: