• React入门与实践


    前言

    在腾讯应用宝前端分享会上分享了react,现将资料整理成这篇文章,希望对react的初学者能够有所帮助;如果文中有描述不恰当或者错误的地方,请望斧正。

    1. 为什么使用react

    react 是facebook在2013年开源的一个javascript库,主要用来快速的构建页面,使用react主要有以下两个原因:

    • 简单的响应式更新。在传统的javascript中,当页面的数据发生变化的时候,我们除了要关注数据的变化,还要更新对应的dom结构,比如一个页面的简单的一个标题This is a title,当其中的内容改为hello world的时候,我们需要如下的操作:
      <h1>This is a title</h1>
      <script>
      var data="hello world";//在实际中是从后台获取数据
      var h1=document.querySelector("h1");
      h1.innerHTML=data;//关注dom结构的变化
      </script>
      如果使用react 的话,只需要将数据设置进去,不需要关注dom结构的变化。
    • 组件化。在react中,我们看到的每一个页面其实都是由一个个组件:header,content,footer等组成,这样可以快速的构建页面,而且还利于组件的复用。

    2. react基础

    2.1 概览

    学习编程语言C++,java可能都是hello world说起的,先看一个简单的hello world的例子:

    <!-- javacript files-->
        <script src="lib/react.js"></script>
        <script src="lib/react-dom.js"></script>
        <script src="lib/browser.min.js"></script>
        //...
        <div id="app"></div>
        <script type="text/babel">
            var HelloWorld = React.createClass({
            render: function() {
            return <h2>Hello World</h2>
            }
        })
          const app =document.getElementById("app");
        ReactDOM.render(<HelloWorld  />, app);
        </script>

    在上面的代码中,我们看到引入了两个库:react.js,react-dom.js,其实使用react的核心库,在0.14版本之前是一个文件,之后分成了两个,react.js包括了组件相关定义的属性、方法,如:react.createClass,react.Componet等;react-dom.js主要是包括了将一个react组件渲染到页面成为真实dom的相关属性,例如:reactDOM.render,findDOMNode。使用react构建一个组件分为以下两步:
    (1)定义一个组件,并给组件一个名称;
    (2)使用reactDOM.render()方法将组件渲染到页面上。

    2.2 组件定义的两种方式

    上面有提到组件,那么react怎么定义一个组件呢。有两种方式定义:React.createClass()与class的方式。

    React.createClass

    这是是react最早的版本提出的一个创建方式,使用的方式是在rener中返回我们需要在页面上看到的dom结构,代码如上图的helloworld例子所示。

    class

    第二种方式是使用class的方式,这可能是跟es6相契合吧,一个比较建议使用这样的方式;大体语法是 class componentName extends React.Component(完整代码见附件demo01中的helloworld.html)。

    class HelloWorld extends React.Component {
                render(){
                    return (
                    <h2>Hello World!</h2>
                    );
                }
            }

    2.3 state vs props

    在组件定义后,其组件的数据是我们关注的焦点。react中定义了两个属性来描述组件的数据props与state;我们可以将一个组件想象成一个函数,其中props就是传递的参数并且不可以在函数内修改;而state就是其中定义的变量,我们可以对其中的变量进行维护。

    export default class Article extends React.Component {
      render() {
        const { title } = this.props;
        return (
          <div >
            <h4>{title}</h4>
       //...
          </div>
        );
      }
    }
    <Article  title={title}/>
    

      

    我们只需要传递标题的值就可以了,不需要进行其他的操作,因此使用props。

      constructor() {
        super();
        this.state = {
          title: "Welcome",
    
        };
      }
    <Header changeTitle={this.changeTitle.bind(this)} title={this.state.title} />
    

      

    这个里面的标题是获取input输入框的值,因此设置为state。演示的效果如下:

    我们可能提出疑问,就是如果我们将一个函数B嵌入到另一个函数A中,在A中设置一个变量(state),那么B中就可以使用参数(props)的形式了,的确是可行的,这是两种不同的组件:smart component,dumb component.可以参考Dan的文章 Presentational and Container Components

    2.4 react中的交互

    react中实现事件绑定的方式是非常简单的,只需要在对应的标签中使用驼峰命名法给其一个绑定的函数即可。最常见的就是一个输入框,我们需要获取其值,因此可以给onChange绑定一个事件。其步骤如下:

    1. 定义一个handleChange函数
    2. 在对应的input 中加入函数的绑定input onChange=handleChange(详细代码参见react-webpack)
      export default class Header extends React.Component {
      handleChange(e) {
      const title = e.target.value;
      this.props.changeTitle(title);
      }
      render() {
          <input value={this.props.title} onChange={this.handleChange.bind(this)} />   
      }
      }
        

    2.5 生命周期

    一个react组件有三种状态:mounting,updating,unmounting
    mounting:React Component被render解析生成对应的dom节点并被插入浏览器的DOM结构的过程。
    updating:当一个组件的状态state发生变化的时候,会进行重新的render过程。
    unmounting:是指一个mounted的React Component对应的DOM节点被从DOM节点移除的过程。

    其每一个生命状态都有封装对应的hook函数,我们可以通过状态的变化过程来进行数据的加载、修改、移除等。以实现页面的初始化和页面数据的更新。以mouting状态为例,在组件渲染之前,我们可以使用getInitalState来指定数据的初始化值,使用componentDidMount来进行ajax请求,从服务器加载数据等操。代码示例可以参照react-webpack/src/components/Content.js

    3. react-router

    当页面是组件构成的什么,就天然的时候做单页面应用,可以在发生某种情况下替换掉组件就可以呈现不同的内容了。在讲react-router使用之前,让我们先看看路由实现的一个大体的原理。
    一个url一般由这几个部分组成:协议、域名、端口、文件路径、文件名、查询条件与hash值,hash值的变化不会使页面进行更新,基于此原理,可以实现页面路由,其过程一般如下:

    • 获取hash的取值情况
    • 给每种hash值注册一个回调函数
    • 利用window.haschange()来监听hash值得变化,并执行相应的回调函数,实现页面的路由。(代码来自http://web.jobbole.com/86407/)
    function Router() {
      this.routes = {};
      this.currentUrl = '';
    }
    Router.prototype.route = function(path, callback) {
      this.routes[path] = callback || function(){};
    };
    Router.prototype.refresh = function() {
      this.currentUrl = location.hash.slice(1) || '/';
      this.routes[this.currentUrl]();
    };
    Router.prototype.init = function() {
      window.addEventListener('load', this.refresh.bind(this), false);
      window.addEventListener('hashchange', this.refresh.bind(this), false);
    }
    window.Router = new Router();
    window.Router.init();

    在html 5标准出现之前history对象的属性与方法比较简单,一般是使用history.back(),history.forward()实现页面的前进与后退。但是在html5中为其添加了新的方法与和一个事件,使其为我们实现页面路由提供了新的方法。其中常用的方法有: history.pushState向当前浏览器的历史堆栈中添加一个新的url; window.onpopstate会在浏览器进行前进后退的时候进行触发。
    react-router对两种方式都有实现,我们可以选择任意一种。其调用方式如下:

       <nav className="navbar navbar-inverse navbar-fixed-top" role="navigation">
                <ul  className='main-menu'>
                      <li><Link to="/">首页</Link></li>
                //...       
                </ul>
       </nav>
       <Router history={browserHistory}>
            <Route path="/" component={Layout}>
                <IndexRoute component={Content}></IndexRoute>
              //...
            </Route>
      </Router>
    

      

  • 相关阅读:
    Node.js :HTTP请求和响应流程
    Node.js :URL、QueryString介绍
    jQuery
    如何angular过滤器进行排序???
    封装jsonp
    原生js的math对象
    Iscrool下拉刷新
    javascript闭包
    javascript对象(3)
    javascript对象(2)
  • 原文地址:https://www.cnblogs.com/zsblogs/p/5794448.html
Copyright © 2020-2023  润新知