ReactJs入门教程

前端已不止于前端-ReactJs初体验

原文写于 2015-04-15 https://github.com/kuitos/kuitos.github.io/issues/21javascript

要说2015年前端届最备受瞩目的技术是啥,固然非ReactJs莫属。做为一个只关注最前沿前端技术的系列,天然少不了关于它的介绍。html

ReactJs简介

  • React最初来自Facebook内部的广告系统项目,项目实施过程当中前端开发遇到了巨大挑战,代码变得愈来愈臃肿且混乱不堪,难以维护。因而痛定思痛,他们决定抛开不少所谓的“最佳实践”,从新思考前端界面的构建方式,因而就有了React。前端

  • React的设计依托于Facebook另外一个叫作FLUX的项目,FLUX是一个为了解决Facebook在MVC应用中碰到的工程性问题而生的设计模式,主要思路是单向数据流。解析 Facebook 的 Flux 应用架构java

  • React是MVC中薄薄的一层V,它只关注表现层,对组件化开发有很大的裨益。node

ReactJs核心特征

  • virtual dom react中的组件跟页面真实dom之间会有一层virtual dom(虚拟dom),virtual dom是内存中的javascript对象,它具备与真实dom一致的树状结构。开发者每次试图更新view,react都会从新构建virtual dom树,而后将其与上一次virtual dom树做对比,依靠react强劲的核心算法dom diff找出真正发生变动的节点,最后映射到真实dom上,这也是react号称性能高效的秘密所在。依赖于virtual dom,对React而言,每一次界面的更新都是总体更新,而不是层叠式更新(即一个复杂的,各个UI之间可能存在互相依赖的时候,每一次独立的更新可能会引起其余UI的变化,假如咱们的目的是更新C的数据,逻辑流极可能是这样的 A -->B-->C-->A-->B–>C,这种状况下中间状态的DOM操做就是极大的浪费)。react

  • 单向数据流 flux架构下的数据流呈现出一种单向、闭环的流动路线,使得一切行为变的可预测,也能更好的定位错误发生点。react官方的卖点之一就是 友好的错误提示(这是在针对angular么哈哈)git

  • 每一个组件都是状态机 react认为组件的数据模型是不可变的,组件的属性不该该被修改。组件关注的只应该是状态,不一样的状态呈现不一样的表现形式。每一个状态下的组件都是一个virtual dom对象,这样react就能直接经过等号对比对象地址判断组件是否被修改从而是否须要更新dom,这也是其能提升性能的缘由之一(空间换时间)。github

  • 组件 一切都是组件 react倡导开发者将view切分红一个个组件从而达到松耦合及重用的目的。开发者构建页面只须要排列组合就好了。算法

  • immutable object React提倡使用只读数据来创建数据模型,每次更新都是new object,这也是dom diff 性能强劲的密码所在(===便可判断两个对象是否相等,而不须要深度遍历)。参考资料 immutable.jsnpm

  • JSX 不是在js里面写html,jsx是xml的javascript表示法。

说了这么多理论性的东西,仍是直接来上代码吧

1. ReactJs开发准备工做

  1. 首先你须要reactjs的开发环境。

    bower install react
  2. 脚本中引入react,因为咱们须要使用jsx语法提升开发效率,因此还须要引入能讲jsx转化为javascript的库
    不过这样JSXTransformer每次都会在app打开的时候作转换工做,并不适合生产环境,转换工做应该放在服务端进行,借助jsx工具

    npm install -g react-tools
    jsx --watch src/ build/

而后页面依赖改为这样
node插件会在你开发的时候自动将源码转成javascript文件到指定目录

2. 第一个react程序

// Hello World
React.render(
    <h1>Hello, world!</h1>,
    document.getElementById('example')
);

3. 接下来咱们介绍一下react的一些基础语法

  1. React.render() 将模版转换成html并插入到指定节点 参见上文的hello world示例

  2. React解析引擎的规则就是遇到<符号就以jsx语法解析,遇到{就以javascript语法解析。好比这样

    var array = [
        <h1>Example 2</h1>,
        <h2>Hello World</h2>
    ];
     
    React.render(
        <div>{array}</div>,
        document.getElementById("example2")
    );

    经过查看转换后的代码,咱们能够看到他摘下面具后长这样

    var array = [
        React.createElement("h1", null, "Example 2"),
        React.createElement("h2", null, "Hello World")
    ];
     
    React.render(
        React.createElement("div", null, array),
        document.getElementById("example2")
    );
  3. 如何建立组件

    var HelloWorldComponent = React.createClass({
        render: function () {
            return <div>React Component {this.props.author}</div>;
        }
    });
     
    React.render(
        <HelloWorldComponent author="Kuitos"/>,
        document.getElementById("hello")
    );

    经过React.createClass能够建立一个关联了虚拟dom的组件对象,每次组件数据更新便会调用组件的 render 方法从新渲染dom。

  4. 组件对象的props属性
    上面一个例子咱们看到在组件render方法中咱们能够经过this.props.xx的方式拿到组件上关联的属性。另外须要额外提到的是,this.props有一个特殊属性children,它指向组件的子节点集合,like this

    var List = React.createClass({
        render: function () {
            return (
                <ol>
                    {
                        this.props.children.map(function (child) {
                            return <li>{child}</li>
                        })
                    }
                </ol>
            );
        }
    });
     
    React.render(
        <List>
            <a href="#">百度</a>
            <a href="#">谷歌</a>
        </List>,
        document.getElementById("example3")
    );

    页面渲染的结果就是一个 ol 列表中还有两个li,每一个li中包含一个超连接。经过这里咱们也能够看出,在jsx中{}是会getValue的

  5. 获取真实dom React.findDOMNode()

    var counter = 0;
    var Button = React.createClass({
     
        handleClick: function () {
            React.findDOMNode(this.refs.input).focus();
        },
     
        render: function () {
     
            return (
                <div>
                    <input type="text" ref="input"/>
                    <input type="button" value="counter" onClick={this.handleClick}/>
                </div>
            );
     
        }
    });
     
    React.render(
        <Button />,
        document.getElementById("button")
    );
  6. 组件状态 this.state

    var Toggle = React.createClass({
     
        getInitialState: function () {
            return {liked: false};
        },
     
        handleClick: function (event) {
            this.setState({liked: !this.state.liked});
        },
     
        render: function () {
     
            var text = this.state.liked ? "like" : "unlike";
     
            return (
                <p onClick={this.handleClick}>
                    U {text} this.
                </p>
            );
        }
    });
     
    React.render(
        <Toggle />,
        document.getElementById("button1")
    );
  7. 用React的方式实现angular中双向绑定的效果

    var Input = React.createClass({
     
        getInitialState: function () {
            return {value: "Kuitos"};
        },
     
        handleChange: function (event) {
            this.setState({value: event.target.value});
        },
     
        render: function () {
     
            var value = this.state.value;
     
            return (
                <div>
                    <p>{value}</p>
                    <input type="text" value={value} onChange={this.handleChange}/>
                </div>
            );
        }
    });
     
    React.render(
        <Input/>,
        document.getElementById("inputDataBind")
    );
  8. virtual dom状态变动回调
    组件生命周期分为三个状态:

    • Mouting: 已插入真实 DOM

    • Updating: 正在被从新渲染

    • Unmounting: 已移出真实 DOM

    • React为每一个状态都提供相应的pre跟post处理函数。只不过React的命名是will(pre 进入状态以前)跟did(post 进入状态以后)。

    • componentWillMount()

    • componentDidMount()

    • componentWillUpdate(Object nextProps, Object nextState)

    • componentDidUpdate(Object prevProps, Object prevState)

    • componentWillUnmount()
      咱们这样写

      var Input = React.createClass({
       
          getInitialState: function () {
              return {firstName: "Kuitos", lastName: "Lau"};
          },
       
          handleChange: function (event) {
              this.setState({firstName: event.target.value});
          },
       
          componentWillMount: function () {
              console.log("dom will be insert", this.state.firstName);
          },
       
          componentDidMount: function () {
              console.log("dom had be insert", this.state.firstName);
          },
       
          componentWillUpdate: function (nextProps, nextState) {
              console.log("dom will be update", nextProps, nextState);
          },
       
          componentDidUpdate: function (prevProps, prevState) {
              console.log("dom had be update", prevProps, prevState);
          },
       
          render: function () {
       
              var state = this.state;
       
              return (
                  <div>
                      <p>{state.firstName} {state.lastName}</p>
                      <input type="text" value={state.firstName} author={state.firstName} onChange={this.handleChange}/>
                  </div>
              );
          }
      });
       
      React.render(
          <Input/>,
          document.getElementById("inputDataBind")
      );

打印的顺序依次是,dom will be update , dom had be update
当input输入时 dom will be update , dom had be update

react的基本知识就介绍到这里,后续咱们会继续介绍react在实战项目中的应用及react native在移动端的表现力。

相关文章
相关标签/搜索