Ajax2015年不过抢手前端框架React 入门实例教程

兹最好热门的前端框架,毫无疑问是 React 。

上周,基于 React 的 React Native 发布,结果一致天内,就收获了 5000
颗星,受瞩目程度可见一斑。

React 起源于 Facebook 的里边项目,因为该商家对市场高达所有 JavaScript MVC
框架,都未满意,就决定好写一仿照,用来架设 Instagram 的网站。做出来后,发现就套东西非常好用,就以2013年5月始于源了。

Ajax 1

出于 React
的统筹思想最突出,属于革命性创新,性能突出,代码逻辑却非常简单。所以,越来越多之丁起关注同应用,认为其可能是明天
Web 开发之主流工具。

其一路本身吗进一步滚越老,从最早的UI引擎变成了一整套前后端连接吃的 Web App
解决方案。衍生的 React Native 项目,目标越来越宏伟,希望就此写 Web App
的办法去描绘 Native
App。如果能够落实,整个互联网行业还见面让颠覆,因为相同组人单待写一次 UI
,就能够而且运行于服务器、浏览器与手机(参见《也许,DOM 不是答案》)。

Ajax 2

既然如此 React
这么红,看上去充满希望,当然应该好好学一下。从技术角度,可以满足好奇心,提高技能水平;从工作角度,有利于求职及升级换代,有利于与潜力大之型。但是,好的
React
教程却休便于找到,这一派为这项技艺最新,刚刚开始走红,大家还没有经历,还以搜寻之中;另一方面因
React 本身还在频频改,API 一直于调整,至今并未公布1.0本。

Ajax 3

自家学习 React
时,就特别窝火。有的教程讨论一些细节问题,对入门没拉;有的教程写得不错,但比较少,无助于看清全貌。我绝对断续续学了几乎个月,看罢二十几篇教程,在是进程中,将针对协调产生帮带的
Demo 都采访下来,做成了一个库 React Demos 。

Ajax 4

下,我便依据这库房,写一首全面而通俗的 React
入门教程。你不过待随着每一个 Demo 做相同整个,就能够起掌握 React
。当然,前提是若不能不具有核心 JavaScript 和 DOM
知识,但是若念了便见面发觉,React 所要求的准备知识真正特别少。
零、安装

React 的安包,可以交官网下载。不过,React Demos 已经从带 React
源码,不用另外安装,只待将这个库拷贝到您的硬盘就尽了。

$ git clone git@github.com:ruanyf/react-demos.git

一经您从未安装 git, 那便直接下载 zip 压缩包。

Ajax 5

脚要教的12个例在一一 Demo 子目录,每个目录都起一个 index.html
文件,在浏览器打开这文件(大多数状态下双击即可),就可知即刻看出成效。

亟待征的凡,React
可以以浏览器运行,也可以服务器运行,但是论学科只关乎浏览器。一方面是为尽可能保障简单,另一方面
React
的语法是一致的,服务器的用法及浏览器差别不要命。Demo13 是服务器首屏渲染之例证,有趣味之情侣可好失去看源码。

一、HTML 模板

动 React 的网页源码,结构大体上如下。

<!DOCTYPE html><html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="../build/browser.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
      // ** Our code goes here! **
    </script>
  </body>
</html>

地方代码有些许独地方得专注。首先,最后一个 script 标签的 type 属性为
text/babel 。这是坐 React 独有的 JSX 语法,跟 JavaScript
不匹配。凡是利用 JSX 的地方,都设加上 type=”text/babel” 。

从,上面代码一共用了三个仓库: react.js 、react-dom.js 和 Browser.js
,它们必须首先加载。其中,react.js 是 React 的基本库,react-dom.js
是供与 DOM 相关的职能,Browser.js 的来意是将 JSX 语法转为 JavaScript
语法,这同步很耗费时间,实际上线之时节,应该用她放到服务器就。

$ babel src --out-dir build

面命令可以以 src 子目录的 js 文件进行语法转换,转码后底文书全部放在
build 子目录。

二、ReactDOM.render()

ReactDOM.render 是 React 的极端核心方式,用于将模板转为 HTML
语言,并插入指定的 DOM 节点。

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

上面代码用一个 h1 题,插入 example 节点(查看 demo01),运行结果如下。

Ajax 6

 

三、JSX 语法

及平等节的代码, HTML 语言直接写在 JavaScript
语言里,不加以其它引号,这虽是 JSX 的语法,它同意 HTML 与 JavaScript
的混写(查看 Demo02 )。

var names = ['Alice', 'Emily', 'Kate'];ReactDOM.render(
  <div>
  {
    names.map(function (name) {
      return <div>Hello, {name}!</div>
    })
  }
  </div>,
  document.getElementById('example')
);

上面代码体现了 JSX 的核心语法规则:遇到 HTML 标签(以 < 开头),就因故
HTML 规则解析;遇到代码块(以{ 开头),就因此 JavaScript
规则解析。上面代码的运行结果如下。

Ajax 7

JSX 允许直接当模板插入 JavaScript
变量。如果这变量是一个屡组,则会开展这数组的保有成员(查看demo03)。

var arr = [
  <h1>Hello world!</h1>,
  <h2>React is awesome</h2>,
];
ReactDOM.render(
  <div>{arr}</div>,
  document.getElementById('example')
);

方代码的arr变量是一个勤组,结果 JSX
会把其的富有成员,添加到模板,运行结果如下。

Ajax 8

四、组件

React 允许用代码封装成组件(component),然后如插入普通 HTML
标签一样,在网页遭到插入这个组件。React.createClass
方法就是用于转移一个零部件类(查看 demo04)。

var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}</h1>;
  }});

ReactDOM.render(
  <HelloMessage name="John" />,
  document.getElementById('example')
);

面代码中,变量 HelloMessage 就是一个零部件类。模板插入 <HelloMessage
/> 时,会自动生成 HelloMessage
的一个实例(下文的”组件”都指组件类的实例)。所有组件类都必须出协调的
render 方法,用于出口组件。

零件的用法及原生的 HTML 标签完全一致,可以无限制加入性,比如
<HelloMessage name=”John” /> ,就是 HelloMessage 组件加入一个 name
属性,值为 John。组件的特性可以在组件类的 this.props 对象及取得,比如
name 属性就好透过 this.props.name 读取。上面代码的周转结果如下。

Ajax 9

丰富零件属性,有一个地方用小心,就是 class 属性需要写成 className
,for 属性需要写成 htmlFor ,这是盖 class 和 for 是 JavaScript
的保留字。

五、this.props.children

this.props 对象的性质和组件的习性一一对应,但是有一个异,就是
this.props.children 属性。它象征组件的所有子节点(查看 demo05)。

var NotesList = React.createClass({
  render: function() {
    return (
      <ol>
      {
        React.Children.map(this.props.children, function (child) {
          return {child};
        })
      }
      </ol>
    );
  }
});

ReactDOM.render(
 
   hello
   world
 
,
 document.body
);

上面代码的 NoteList 组件有零星单 span 子节点,它们还可以经
this.props.children 读取,运行结果如下。

Ajax 10

此间要注意, this.props.children
的价有三栽可能:如果手上组件没有子节点,它就是是 undefined
;如果出一个子节点,数据类型是 object ;如果发差不多个子节点,数据类型就是
array 。所以,处理this.props.children 的时节要小心。

React 提供一个家伙方法 React.Children 来拍卖 this.props.children
。我们可用 React.Children.map来举历子节点,而不用担心
this.props.children 的数据类型是 undefined 还是
object。更多之React.Children 的艺术,请参考官方文档。

六、PropTypes

组件的性质可以接受任意值,字符串、对象、函数等等都得以。有时,我们得平等栽体制,验证别人使用组件时,提供的参数是否符合要求。

零件类的PropTypes属性,就是之所以来说明组件实例的性质是否符合要求(查看 demo06)。

var MyTitle = React.createClass({
  propTypes: {
    title: React.PropTypes.string.isRequired,
  },

 render: function() {
    return

{this.props.title}

;
  }
});

面的Mytitle组件有一个title属性。PropTypes 告诉 React,这个 title
属性是必须的,而且它的价必须是字符串。现在,我们装 title
属性的价值是一个数值。

var data = 123;

ReactDOM.render(
  <MyTitle title={data} />,
  document.body
);

这样一来,title属性就接入不了证明了。控制台会显示一行错误信息。

Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.

重复多的PropTypes设置,可以查官方文档。

除此以外,getDefaultProps 方法可以用来安装组件属性之默认值。

var MyTitle = React.createClass({
  getDefaultProps : function () {
    return {
      title : 'Hello World'
    };
  },

  render: function() {
     return <h1> {this.props.title} </h1>;
   }
});

ReactDOM.render(
  <MyTitle />,
  document.body);

点代码会输出”Hello World”。

七、获取真实的DOM节点

组件并无是真性的 DOM 节点,而是在让内存之中的一律种植多少结构,叫做虚拟
DOM (virtual DOM)。只有当其插入文档以后,才会化实际的 DOM 。根据
React 的筹划,所有的 DOM 变动,都先以虚拟 DOM
上闹,然后还将实际有转移的部分,反映在实际 DOM上,这种算法叫做 DOM
diff ,它好大幅度增进网页的性表现。

不过,有时要由组件获取真实 DOM 的节点,这时就要用到 ref
属性(查看 demo07 )。

var MyComponent = React.createClass({
  handleClick: function() {
    this.refs.myTextInput.focus();
  },
  render: function() {
    return (
      <div>
        <input type="text" ref="myTextInput" />
        <input type="button" value="Focus the text input" onClick={this.handleClick} />
      </div>
    );
  }
});

ReactDOM.render(
 ,
 document.getElementById(‘example’)
);

地方代码中,组件 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 (查看 demo08 )。

var LikeButton = React.createClass({
  getInitialState: function() {
    return {liked: false};
  },
  handleClick: function(event) {
    this.setState({liked: !this.state.liked});
  },
  render: function() {
    var text = this.state.liked ? 'like' : 'haven\'t liked';
    return (
      <p onClick={this.handleClick}>
        You {text} this. Click to toggle.
      </p>
    );
  }
});

ReactDOM.render(
 ,
 document.getElementById(‘example’)
);

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

鉴于 this.props 和 this.state
都用于描述组件的特点,可能会见有模糊。一个粗略的界别方法是,this.props
表示那些要定义,就不再改变的性状,而 this.state
是会见随着用户互动而产生变化之特性。

九、表单

用户以表单填入的情,属于用户和组件的竞相,所以无克用 this.props
读取(查看 demo9 )。

var Input = React.createClass({
  getInitialState: function() {
    return {value: 'Hello!'};
  },
  handleChange: function(event) {
    this.setState({value: event.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(<Input/>, document.body);

地方代码中,文本输入框的价,不可知就此 this.props.value 读取,而使定义一个
onChange 事件之回调函数,通过 event.target.value
读取用户输入的价值。textarea
元素、select元素、radio元素都属于这种情况,更多介绍请参考官方文档。

十、组件的生命周期

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

  • Mounting:已插入真实 DOM

  • Updating:正在吃再度渲染

  • Unmounting:已变有真实 DOM

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

  • componentWillMount()

  • componentDidMount()

  • componentWillUpdate(object nextProps, object nextState)

  • componentDidUpdate(object prevProps, object prevState)

  • componentWillUnmount()

另外,React 还提供简单栽特有状态的处理函数。

  • componentWillReceiveProps(object
    nextProps):已加载组件收到新的参数时调用

  • shouldComponentUpdate(object nextProps, object
    nextState):组件判断是否再渲染时调用

这些点子的详尽说明,可以参考官方Ajax文档。下面是一个例证(查看 demo10 )。

var Hello = React.createClass({
  getInitialState: function () {
    return {
      opacity: 1.0
    };
  },

  componentDidMount: function () {
    this.timer = 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(
  <Hello name="world"/>,
  document.body);

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

另外,组件的style属性的装方式吧值得注意,不能够写成

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

倘若设写成

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

眼看是盖 React 组件样式是一个目标,所以首先要害括号表示这是 JavaScript
语法,第二重大括号表示样式对象。

十一、Ajax

零件的数量出自,通常是通过 Ajax 请求于服务器获取,可以利用
componentDidMount 方法设置 Ajax 请求,等到请求成功,再就此 this.setState
方法重复渲染 UI (查看 demo11 )。

var UserGist = React.createClass({
  getInitialState: function() {
    return {
      username: '',
      lastGistUrl: ''
    };
  },

  componentDidMount: function() {
    $.get(this.props.source, function(result) {
      var lastGist = result[0];
      if (this.isMounted()) {
        this.setState({
          username: lastGist.owner.login,
          lastGistUrl: lastGist.html_url        });
      }
    }.bind(this));
  },

  render: function() {
    return (
      <div>
        {this.state.username}'s last gist is
        <a href={this.state.lastGistUrl}>here</a>.
      </div>    );
  }
});

ReactDOM.render(
  <UserGist source="https://api.github.com/users/octocat/gists" />,
  document.body
);

点代码应用 jQuery 完成 Ajax 请求,这是以方便说明。React
本身并未其它借助,完全可毫无jQuery,而采用外库。

咱俩还是好管一个Promise对象传入组件,请圈Demo12。

ReactDOM.render(
  <RepoList
    promise={$.getJSON('https://api.github.com/search/repositories?q=javascript&sort=stars')}
  />,
  document.body
);

地方代码从Github的API抓取数据,然后用Promise对象作为性能,传于RepoList组件。

假若Promise对象在抓取数据(pending状态),组件显示”正在加载”;如果Promise对象报错(rejected状态),组件显示报错信息;如果Promise对象抓到手多少成功(fulfilled状态),组件显示得之多少。

var RepoList = React.createClass({
  getInitialState: function() {
    return { loading: true, error: null, data: null};
  },

 componentDidMount() {
   this.props.promise.then(
     value => this.setState({loading: false, data: value}),
     error => this.setState({loading: false, error: error}));
 },

 render: function() {
   if (this.state.loading) {
     return Loading…;
   }
   else if (this.state.error !== null) {
     return Error: {this.state.error.message};
   }
   else {
     var repos = this.state.data.items;
     var repoList = repos.map(function (repo) {
       return (
         

  •            {repo.name} ({repo.stargazers_count} stars)
    {repo.description}
             
  •        );
         });
         return (
           


             

    Most Popular JavaScript Projects in Github

             

      {repoList}

           


         );
       }
     }
    });

    十二、参考链接

    1. React’s official site

    2. React’s official examples

    3. React (Virtual) DOM Terminology, by Sebastian Markbge

    4. The React Quick Start Guide, by Jack Callister

    5. Learning React.js: Getting Started and Concepts, by Ken Wheeler

    6. Getting started with React, by Ryan Clark

    7. React JS Tutorial and Guide to the Gotchas, by Justin Deal

    8. React Primer, by Binary Muse

    9. jQuery versus React.js thinking, by zigomir

    作者:阮一峰原文地址:http://www.ruanyifeng.com/blog/2015/03/react.html

    相关文章