摘自阮一峰:React入门实例教程,转载请注明出处。

一、获取真实的DOM节点

  组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。

  但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性。

  1. var MyComponent = React.createClass({
  2.   handleClick: function() {
  3.     this.refs.myTextInput.focus();
  4.   },
  5.   render: function() {
  6.     return (
  7.       <div>
  8.         <input type="text" ref="myTextInput" />
  9.         <input type="button" value="Focus the text input" onClick={this.handleClick} />
  10.       </div>
  11.     );
  12.   }
  13. });
  14.  
  15. ReactDOM.render(
  16.   <MyComponent />,
  17.   document.getElementById('example')
  18. );

  上面代码中,组件 MyComponent 的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点。

  需要注意的是,由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。

  React 组件支持很多事件,除了 Click 事件以外,还有 KeyDown 、Copy、Scroll 等,完整的事件清单请查看官方文档。

二、this.state 组件状态

  组件免不了要与用户互动,React的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI。

  1. var LikeButton = React.createClass({
  2.   getInitialState: function() { //定义初始状态,也就是一个对象
  3.     return {liked: false};
  4.   },
  5.   handleClick: function(event) {
  6.     this.setState({liked: !this.state.liked}); //通过this.state属性读取定义的状态
  7.                           //每次修改以后,自动调用 this.render 方法,再次渲染组件
  8.   },
  9.   render: function() {
  10.     var text = this.state.liked ? 'like' : 'haven\'t liked';
  11.     return (
  12.       <p onClick={this.handleClick}>
  13.       You {text} this. Click to toggle.
  14.       </p>
  15.     );
  16.   }
    });
  17.  
  18. ReactDOM.render(
  19.   <LikeButton />,
  20.   document.getElementById('example')
  21. );

  上面代码是一个 LikeButton 组件,它的 getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。

  由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

三、表单

  用户在表单填入的内容,属于用户跟组件的互动,所以不能用 this.props 读取。

  1. var Input = React.createClass({
  2.   getInitialState: function() {
  3.     return {value: 'Hello!'};
  4.   },
  5.   handleChange: function(event) {
  6.     this.setState({value: event.target.value});
  7.   },
  8.   render: function () {
  9.     var value = this.state.value;
  10.     return (
  11.       <div>
  12.         <input type="text" value={value} onChange={this.handleChange} />
  13.         <p>{value}</p>
  14.       </div>
  15.     );
  16.   }
  17. });
  18.  
  19. ReactDOM.render(<Input/>, document.body);

  上面代码中,文本输入框的值,不能用 this.props.value 读取,而要定义一个 onChange 事件的回调函数,通过 event.target.value 读取用户输入的值。textarea 元素、select元素、radio元素都属于这种情况.

四、组件的生命周期

  组件的生命周期分成三个状态:

  1. Mounting:已插入真实 DOM
  2. Updating:正在被重新渲染
  3. Unmounting:已移出真实 DOM

  React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。

  1. componentWillMount()
  2. componentDidMount()
  3. componentWillUpdate(object nextProps, object nextState)
  4. componentDidUpdate(object prevProps, object prevState)
  5. componentWillUnmount()

  此外,React 还提供两种特殊状态的处理函数。

  1. componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
  2. shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用

  下面是一个例子。

  1. var Hello = React.createClass({
  2.   getInitialState: function () {
  3.     return {
  4.       opacity: 1.0
  5.     };
  6.   },
  7.  
  8.   componentDidMount: function () {
  9.     this.timer = setInterval(function () {
  10.       var opacity = this.state.opacity;
  11.       opacity -= .05;
  12.       if (opacity < 0.1) {
  13.         opacity = 1.0;
  14.       }
  15.       this.setState({
  16.         opacity: opacity
  17.       });
  18.     }.bind(this), 100);
  19.   },
  20.  
  21.   render: function () {
  22.     return (
  23.       <div style={{opacity: this.state.opacity}}>
  24.         Hello {this.props.name}
  25.       </div>
  26.     );
  27.   }
  28. });
  29.  
  30. ReactDOM.render(
  31.   <Hello name="world"/>,
  32.   document.body
  33. );

  上面代码在hello组件加载以后,通过 componentDidMount方法设置一个定时器,每隔100毫秒,就重新设置组件的透明度,从而引发重新渲染。

  另外,组件的style属性的设置方式也值得注意,不能写成

  1. style="opacity:{this.state.opacity};"

  而要写成

  1. style={{opacity: this.state.opacity}}

  这是因为 React 组件样式是一个对象,所以第一重大括号表示这是 JavaScript 语法,第二重大括号表示样式对象。

五、Ajax

  组件的数据来源,通常是通过 Ajax 请求从服务器获取,可以使用 componentDidMount 方法设置 Ajax 请求,等到请求成功,再用 this.setState 方法重新渲染 UI.

  1. var UserGist = React.createClass({
  2.   getInitialState: function() {
  3.     return {
  4.       username: '',
  5.       lastGistUrl: ''
  6.     };
  7.   },
  8.  
  9.   componentDidMount: function() {
  10.     $.get(this.props.source, function(result) {
  11.       var lastGist = result[0];
  12.       if (this.isMounted()) {
  13.         this.setState({
  14.           username: lastGist.owner.login,
  15.           lastGistUrl: lastGist.html_url
  16.         });
  17.       }
  18.     }.bind(this));
  19.   },
  20.  
  21.   render: function() {
  22.     return (
  23.       <div>
  24.         {this.state.username}'s last gist is
  25.         <a href={this.state.lastGistUrl}>here</a>.
  26.       </div>
  27.     );
  28.   }
  29. });
  30.  
  31. ReactDOM.render(
  32.   <UserGist source="https://api.github.com/users/octocat/gists" />,
  33.   document.body
  34. );

  上面代码使用 jQuery 完成 Ajax 请求,这是为了便于说明。React 本身没有任何依赖,完全可以不用jQuery,而使用其他库。

React 入门学习笔记2的更多相关文章

  1. React 入门学习笔记整理目录

    React 入门学习笔记整理(一)--搭建环境 React 入门学习笔记整理(二)-- JSX简介与语法 React 入门学习笔记整理(三)-- 组件 React 入门学习笔记整理(四)-- 事件 R ...

  2. React 入门学习笔记1

    摘自阮一峰:React入门实例教程,转载请注明出处. 一. 使用React的html模板 使用React, 我们需要加载3个库,react.js, react-dom.js, 和browser.js. ...

  3. React 入门学习笔记整理(一)——搭建环境

    使用create-react-app脚手架搭建环境 1.安装node .软件下载地址:https://nodejs.org/en/,我下的推荐的版本. 安装之后测试是否安装成功.windows系统下, ...

  4. React 入门学习笔记整理(二)—— JSX简介与语法

    先看下这段代码: import React from 'react'; //最终渲染需要调用ReactDOM库,将jsx渲染都页面中 import ReactDOM from 'react-dom'; ...

  5. React 入门学习笔记整理(三)—— 组件

    1.定义组件 1)函数组件 function GreateH(props){ return <div> <h2>hello,{props.name}</h2> &l ...

  6. React 入门学习笔记整理(四)—— 事件

    1.事件定义 React事件绑定属性的命名采用驼峰式写法,而不是小写. 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM元素的写法) 在类组件中定义函数,通过thi ...

  7. React 入门学习笔记整理(五)—— state

    1.state 1)组件本省也是有状态的,定义在组件内部的state中,state的状态只能由组件自身改变,任何其他组件都不能改变. 当需要改变state时,通过调用setState方法来改变,set ...

  8. React 入门学习笔记整理(六)—— 组件通信

    1.父子组件通信 1)父组件与子组件通信,使用Props 父组件将name传递给子组件 <GreateH name="kitty"/> 子组件通过props接收父组件的 ...

  9. React 入门学习笔记整理(七)—— 生命周期

    (1)react 生命周期 只有类组件有生命周期,函数组件没有生命周期 1.挂载阶段:这些方法会在组件实例被创建和插入DOM中时被调用: 1)constructor(props) 初始化组件的状态.绑 ...

随机推荐

  1. windows主机网络信息获取程序设计

    掌握windows系统获取网络信息的各种API函数的功能与调用方法,掌握设计程序显示获取到相关网络信息的方法,掌握网络字节数据与主机字节数据之间的转换.掌握这些API函数调用的错误处理方法. 利用本地 ...

  2. Java 源程序与编译型运行区别

  3. java设计模式-----19、迭代模式

    概念: Iterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式. 迭代模式使用比较少,JDK集合也提供 ...

  4. EF CodeFirst 初识

    随着EntityFramework的发展,原先的三种方式,{Code First ,Model First,Database First }  CodeFirst基本摆脱了另外两种方式 成为了 最受欢 ...

  5. 有趣:256个class选择器可以干掉1个id选择器——张鑫旭

    我们应该都知道,从选择器得分权重上将,id选择器(#aaa{})和class选择器(.aaa{})完全不是一个数量级的,前者:1-0-0; 而后者为0-1-0.因此: #id { color:dark ...

  6. CSS中width和height与盒子模型的关系

    盒子模型 css中盒子模型包含属性margin.border.padding.width与height,他们可以把它转移到我们日常生活中的盒子(箱子)上来理解,日常生活中所见的盒子也具有这些属性,所以 ...

  7. 基于Udp的五子棋对战游戏

    引言 本文主要讲述在局域网内,使用c#基于Udp协议编写一个对战的五子棋游戏.主要从Udp的使用.游戏的绘制.对战的逻辑这三个部分来讲解. 开发环境:vs2013,.Net4.0,在文章的末尾提供源代 ...

  8. 【代码笔记】iOS-gif图片播放

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...

  9. python之定义函数

    1.定义函数和参数检查 通过def语句定义一个函数,自己定义的函数,当参数个数不对时,python解释器可以抛出TypeError,但是当参数类型不对时,无法抛出TypeError,为此可以通过isi ...

  10. 深入理解net core中的依赖注入、Singleton、Scoped、Transient(二)

    相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transient(一) 深入理解net core中的依赖注入.Singleton.Scoped.Transient ...