zoukankan      html  css  js  c++  java
  • React.js基础入门

    本文主要是针对React的一些demo教程。参考了菜鸟教程中的react教程,做了一些总结。Demo的下载链接是

    https://github.com/RealAndMe/react-demo
    

    下面要讲解的例子都在对应的demo中。

    从github下载react-demo需要用到的命令行:

    #下载代码
    $ git clone git@github.com:RealAndMe/react-demo.git
    
    #安装开发所依赖的模块
    $ npm install
    
    #运行并监听
    $ gulp watch
    
    #具体的可以查看之前的相关博客
    

    目录结构

    目录结构

    build文件夹里是需要用到的js库文档

    • jquery.js
    • react.js
    • react-dom.js
    • ……

    每一个demo文件夹都有
    .html和.js两个文档,其中js文档中放的是主要的JSX功能,html是渲染的

    HTML模板

    <!DOCTYPE html>
    <html>
    <head>
    	<meta charset="utf-8">
    	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    	<title></title>
    	<script src="../build/react.js"></script>
    	<script src="../build/react-dom.js"></script>
    	<script src="../build/browser.min.js"></script>
    </head>
    <body>
    	<div id="contain"></div>
    	<script type="text/babel" src="index.js"></script>
    </body>
    </html>
    

    用到的React必须的库:

    • react.js 是react的核心库
    • react-dom.js 是提供与DOM相关的功能
    • browser.min.js 是将JSX语法转换为javascript语法。

    注意:React使用独有的JSX,与javascript不兼容,所以凡是使用JSX的地方,都要加上<script type="text/babel"></script>

    demo01

    这里.js后缀的文档里存放的是React的JSX语法,它是用来代替常规的javascript,执行速度更快。

    ReactDOM.render(<div>hello,world!</div>,document.getElementById("contain"));
    

    ReactDOM.render()方法是将JSX转换为HTML方法,并将其呈现到指定的DOM节点中,是React的基本语法。

    JSX基本语法规则:遇到HTML标签(以 < 开头),就用HTML规则解析;遇到代码块(以 { 开头),就用JavaScript规则解析。

    上面代码是将<div>块插入到contain的节点中(查看demo01

    demo02

    React.createClass()方法生成一个React组件类,类名首字母必须大写。(查看demo02

    每个组件都有一个render : function(){}的函数,用来输出组件,并且函数里都有return返回值。return里描述的就是HTML树结构,只能包含一个顶层标签。。

    <Demo02 />实例化组件类并输出信息。

    var Demo02 = React.createClass({
    	render : function(){
    		return(
    			<div className="demo02">hello,world!</div>
    		)
    	}
    });
    ReactDOM.render(<Demo02 />,document.getElementById("contain"));
    

    可以给标签添加样式,在html中添加类是class,但是在JSX中是calssName,而for属性要写成htmlFor,这是因为for和class是javascript的保留字。

    demo03

    在JSX中使用javascript的数组,样式。(查看demo03

    我们可以添加内联样式。React会在指定元素数字后面自动添加px。

    javascript代码块都要用花括号{ },注释也需要写在花括号中。

    var array = ["lilei","wangdong","yulun"];
    
    /*定义样式*/
    var myStyle = {
    	fontSize: 100,
    	color: "red",
    	textAlign: "center"
    };
    
    var Demo03 = React.createClass({
    	render : function(){
    		return(
    			<div style={myStyle}>
    			{/*遍历数组*/}
    			{
    				array.map(function(msg,index){
    					return <div key={index}>hello,{msg}</div>
    				})
    			}
    			</div>
    		)
    	}
    });
    ReactDOM.render(<Demo03 />,document.getElementById("contain"));
    

    数组遍历的时候会有警告提示表示要加上一个key属性,这个key是用来保证react-vdom标识的唯一性。

    key属性

    demo04

    组件将具有属性,可以使用this.props.[attribute]来访问,attribute是对应的属性的名称。

    (查看demo04

    var Demo04 = React.createClass({
    	render : function(){
    		return(
    			<div>hello,{this.props.name}</div>
    		)
    	}
    });
    ReactDOM.render(<Demo04 name="wjy" />,document.getElementById("contain"));
    

    上述代码中就是通过this.props.name获取组件上的name属性。

    demo05

    this.props.childre属性表示组件的所有子节点。(查看demo05

    React.children.map(this.props.children,function(){})方法用来遍历子节点的。

    var Demo05 = React.createClass({
        render : function(){
            return(
                <ol>
                {
            	React.Children.map(this.props.children,function(msg){
                    return <li>{msg}</li>
                	})
                }
                </ol>
                )
            }
    });
    ReactDOM.render(
    	<Demo05>
    		<span>你好</span>
    		<span>hello,world</span>
    	</Demo05>,
    	document.getElementById("contain")
    );
    

    上述代码中,组件<Demo05 />中有两个子节点,可以通过this.props.children来读取。

    this.props.children的值有三种情况:

    • 当前组件没有子节点,它的数据类型是undefined
    • 只有一个子节点,它的数据类型是object
    • 多个子节点,它的数据类型是array

    所以要小心处理this.props.children属性。

    demo06

    组件的属性有很多种类型,比如:数值、字符串等,可以通过React.propTypes来验证props是否有效。当传入的是无效的数据时,控制台会抛出一个异常。(查看demo06

    //var flag = "字符串类型";
    var flag = 123;
    
    var Demo06 = React.createClass({
    	propTypes : {
    		title : React.PropTypes.string.isRequired
    	},
    	render : function(){
    		return(
    			<h1>{this.props.title}</h1>
    		)
    	}
    });
    ReactDOM.render(<Demo06 title={flag}/>,document.getElementById("contain"));
    

    上述代码中,组件<Demo06 />有一个title属性,PropType告诉React,title属性是必须的,并且数据类型是字符串型。这里我们给title设置一个数值,这个时候属性验证不通过,控制台会有一个异常信息。

    demo07

    getDefaultProps()方法是为props设置默认值。(查看demo07

    var Demo07 = React.createClass({
    	getDefaultProps : function() {
    		return{
    			title : "wangyu"
    		}
    	},
    	
    	render : function(){
    		return(
    			<h1>hello,{this.props.title}</h1>
    		)
    	}
    });
    ReactDOM.render(<Demo07 />,document.getElementById("contain"));
    

    demo08

    虚拟DOM:组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构。

    只有在虚拟DOM插入到文档之后,才会变成真实DOM。

    DOM diff算法:根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上。这样提高了网页的性能表现。

    从组件中获取真实的DOM节点,使用ref属性。(查看demo08

    var Demo08 = React.createClass({
    	handleClick : function(){
    		/*用原生的方法focus()获取文本框焦点*/
    		this.refs.textInput.focus();
    	},
    	render : function(){
    		//  当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs,这是在真实的Dom上进行的
    		return(
    			<div>
    				<input type="text" ref="textInput"/>
    				<br/>
    				<br/>
    				<input type="button" value="点击获取焦点" onClick={this.handleClick}/>
    			</div>
    		)
    	}
    });
    ReactDOM.render(<Demo08 / >, document.getElementById("contain"));
    

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

    注意:由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。

    上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。

    demo09

    React将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI (查看demo09

    var Demo09 = React.createClass({
        getInitialState: function(){
            return {like: false};
        },
        handleClick: function(){
            this.setState({like:!this.state.like});
        },
        render: function() {
            var text = this.state.like?"喜欢":"不喜欢";
            return (
                <div>
                    <p>我{text}你</p>
                    <input value = "点击切换状态" type = "button" onClick = {this.handleClick}/>
                </div>
            );
        }
    });
    ReactDOM.render(<Demo09 />,document.getElementById("contain"));
    

    上述代码中,getInitialState()方法定义state初始化的状态,return返回的是一个对象。当用户点击按钮,导致状态改变时,this.setState({})方法用来修改state状态值,每次修改之后,都会自行调用this.render()方法,再次渲染组件。

    这个对象可以通过this.state.[stateName]属性来获取,stateName是定义的状态的名称。

    this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

    demo10

    表单组件中的value属性(比如:<input>,<textarea>,<option>,<select>)不受任何用户输入的影响,如果要更新或访问该值来响应用户的输入,那么需要用onChange事件来回调。(查看demo10

    var Demo10 = React.createClass({
    	getInitialState: function(){
    		return {
    			value: "你好"
    		};
    	},
    	handleChange: function(e){
    		this.setState({value: e.target.value});
    	},
    	render: function(){
    		var value = this.state.value;
    		return (
    			<div>
    				<input type="text" value={value} onChange={this.handleChange} />
    				<p>{value}</p>
    			</div>
    		);
    	}
    });
    ReactDOM.render(<Demo10 />,document.getElementById("contain"));
    

    上述代码中,文本框输入的值需要用 onChange 事件的回调函数,通过 event.target.value 读取用户输入的值。textarea 元素、select元素、radio元素都属于这种情况

    demo11

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

    • Mounting:已插入真实的DOM
    • Updating:正在被重新渲染
    • Unmounting已移出真实的DOM

    生命周期的方法总共有7种:

    will函数在进入状态之前调用,did在进入状态之后调用。

    • componentWillMount在渲染之前调用
    • componentDidMount在第一次渲染之后调用。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)。
    • componentWillReceiveProps组件接收到新的prop时调用,在初始化render时不调用。
    • shouldComponentUpdate组件判断是否需要重新渲染时
    • componentWillUpdate组件在接收到新的prop或state但还没有渲染时
    • componentDidUpdate组件完成更新后调用
    • componentWillUnmount组件在DOM移出后调用
    var Demo11 = React.createClass({
    	getDefaultProps: function(){
    		return {name: "wjy"};
    	},
    	getInitialState: function () {
        	return {opacity: 1.0};     
        },
      componentDidMount: function () {
        setInterval(function () {
          var opacity = this.state.opacity;
          opacity -= .05;
          if (opacity < 0.1) {
            opacity = 1.0;
          }
          this.setState({
            opacity: opacity
          });
        }.bind(this), 100);
      },
      render: function () {
        return (
          <div style={{opacity: this.state.opacity}}>
            Hello {this.props.name}
          </div>
        );
      }
    });
    ReactDOM.render(<Demo11 />,document.getElementById("contain"));
    

    在组件<Demo11 />加载完之后,通过该componentDidMount方法设置setInterval(function(){},time)定时器,每100ms重新设置组件透明度,然后重新渲染。(查看demo11

    其中给函数加上bind(this)是为了给当前的对象绑定事件,防止出错

    组件的样式要注意,React 组件样式是一个对象,所以第一重大括号表示这是 JavaScript 语法,第二重大括号表示样式对象

    style={{opacity: this.state.opacity}}   //正确写法
    

    demo12

    React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。(查看demo12

    var Demo12 = React.createClass({
        getInitialState: function() {
            return {
                username: '',
                lastGistUrl: ''
            };
        },
        componentDidMount: function() {
           /* 
            *jquery ajax——get()方法通过远程HTTP GET请求载入信息,取代复杂$.ajax
           $.get(this.props.source,function(data){
                var lastGist = data[0];
                if(this.isMounted()){
                    this.setState({
                        username: lastGist.owner.login,
                        lastGistUrl: lastGist.html_url
                    });
                };
            }.bind(this));*/
            $.ajax({
                url: this.props.source,
                type: "get",
                success: function(data){
                    var lastGist = data[0];
                    if(this.isMounted()){
                        this.setState({
                            username: lastGist.owner.login,
                            lastGistUrl: lastGist.html_url
                        });
                    };  
                }.bind(this)
            });
        },
        render: function() {
            return (
              <div>
                {this.state.username}用户最新的共享地址: <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a>
              </div>
            );
        }
    });
    ReactDOM.render(<Demo12 source="https://api.github.com/users/octocat/gists"/>,document.getElementById("contain"));
    

    $
    上述代码中,利用了jQuery的ajax()方法来获取服务器端的数据,也可以通过jquery的ajax的$.get(url,data,sucess(),dataType)方法通过远程HTTP GET请求载入信息,取代复杂$.ajax。

    注意:在函数中经常会用到bind(this),这里的this指向就是componentDidMount()中的this也就是这个react对象,这样才能够正确访问react属性方法this.state,this.setState

    demo13

    JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员。查看demo13

    var Demo13 = React.createClass({
        render: function() {
            var array = [
                <h1>你好!</h1>,
                <h2>hello,world!</h2>
            ];
            return (
              <div>{array}</div>
            );
        }
    });
    ReactDOM.render(<Demo13 />,document.getElementById("contain"));
    

    上面代码的array变量是一个数组,结果 JSX 会把它的所有成员,添加到模板中。

    有道云笔记参考:http://note.youdao.com/noteshare?id=93e15b78b01eca521abc083659c7f356&sub=4CA29FC7AE614755889C60A513DDAF44

  • 相关阅读:
    统计nginx日志里访问次数最多的前十个IP
    while 格式化输出 运算符 字符编码
    Python 软件安装
    Python 基础
    Typora 基础的使用方法
    Django ORM (四) annotate,F,Q 查询
    Django 惰性机制
    Django ORM (三) 查询,删除,更新操作
    Django ORM (二) 增加操作
    Django ORM (一) 创建数据库和模型常用的字段类型参数及Field 重要参数介绍
  • 原文地址:https://www.cnblogs.com/real-me/p/7143590.html
Copyright © 2011-2022 走看看