[转]React 入门实例教程

前端之家收集整理的这篇文章主要介绍了[转]React 入门实例教程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。


React 入门实例教程


作者:阮一峰

日期:2015年3月31日

现在最热门的前端框架,毫无疑问是React

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

React 起源于 Facebook 的内部项目,因为该公司对市场上所有JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设Instagram的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。

由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。

这个项目本身也越滚越大,从最早的UI引擎变成了一整套前后端通吃的 Web App 解决方案。衍生的 React Native 项目,目标更是宏伟,希望用写 Web App 的方式去写 Native App。如果能够实现,整个互联网行业都会被颠覆,因为同一组人只需要写一次 UI ,就能同时运行在服务器、浏览器和手机(参见《也许,DOM 不是答案》)。

既然 React 这么热门,看上去充满希望,当然应该好好学一下。从技术角度,可以满足好奇心,提高技术水平;从职业角度,有利于求职和晋升,有利于参与潜力大的项目。但是,好的 React 教程却不容易找到,这一方面因为这项技术太新,刚刚开始走红,大家都没有经验,还在摸索之中;另一方面因为 React 本身还在不断变动,API 一直在调整,至今没发布1.0版。

我学习 React 时,就很苦恼。有的教程讨论一些细节问题,对入门没帮助;有的教程写得不错,但比较短,无助于看清全貌。我断断续续学了几个月,看过二十几篇教程,在这个过程中,将对自己有帮助的 Demo 都收集下来,做成了一个库React Demos

下面,我就根据这个库,写一篇全面又易懂的 React 入门教程。你只需要跟着每一个 Demo 做一遍,就能初步掌握 React 。当然,前提是你必须拥有基本 JavaScript 和 DOM 知识,但是你读完就会发现,React 所要求的预备知识真的很少。

零、安装

React 的安装包,可以到官网下载。不过,React Demos已经自带 React 源码,不用另外安装,只需把这个库拷贝到你的硬盘就行了。

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

如果你没安装 git, 那就直接下载zip 压缩包

下面要讲解的12个例子在各个Demo子目录,每个目录都有一个index.html文件,在浏览器打开这个文件(大多数情况下双击即可),就能立刻看到效果。

需要说明的是,React 可以在浏览器运行,也可以在服务器运行,但是本教程只涉及浏览器。一方面是为了尽量保持简单,另一方面 React 的语法是一致的,服务器的用法与浏览器差别不大。Demo13是服务器首屏渲染的例子,有兴趣的朋友可以自己去看源码。

一、HTML 模板

使用 React 的网页源码,结构大致如下。

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

上面代码有两个地方需要注意。首先,最后一个<script>标签type属性text/babel。这是因为 React 独有的 JSX 语法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上type="text/babel"

其次,上面代码一共用了三个库:react.jsreact-dom.jsBrowser.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>getElementById('example') );

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

三、JSX 语法

上一节的代码, HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是JSX 的语法,它允许 HTML 与 JavaScript 的混写(查看Demo02)。

var names = ['Alice''Emily''Kate']; ReactDOM<div> { namesmap(function (name) { return {name}> }) } 上面代码体现了 JSX 的基本语法规则:遇到 HTML 标签(以<开头),就用 HTML 规则解析;遇到代码块(以{开头),就用 JavaScript 规则解析。上面代码的运行结果如下。

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

var arr [ >Hello world<h2>React is awesome/h2; ReactDOM{arr上面代码arr变量是一个数组,结果 JSX 会把它的所有成员,添加到模板,运行结果如下。

四、组件

React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类(查看demo04)。

var HelloMessage = ReactcreateClass({ render: function({ >Hello {this.props.name; } <HelloMessage name"John" /上面代码中,变量HelloMessage就是一个组件类。模板插入<HelloMessage />时,会自动生成HelloMessage的一个实例(下文的"组件"都指组件类的实例)。所有组件类都必须有自己的render方法,用于输出组件。

注意,组件类的第一个字母必须大写,否则会报错,比如HelloMessage不能写成helloMessage。另外,组件类只能包含一个顶层标签,否则也会报错。

@H_119_404@> Hello } <p> some text /p上面代码会报错,因为HelloMessage组件包含了两个顶层标签h1p

组件的用法与原生的 HTML 标签完全一致,可以任意加入属性,比如<HelloMessage name="John">,就是HelloMessage组件加入一个name属性,值为John。组件的属性可以在组件类的this.props对象上获取,比如name属性就可以通过this.props.name读取。上面代码的运行结果如下。

添加组件属性,有一个地方需要注意,就是class属性需要写成classNamefor属性需要写成htmlFor,这是因为classfor是 JavaScript 的保留字。

五、this.props.children

this.props对象的属性与组件的属性一一对应,但是有一个例外,就是this.props.children属性。它表示组件的所有子节点(查看demo05)。

var NotesList return ( <ol> { React.Children(this.children(child{ <li{child/li; ) } /ol<NotesList<span>hello/span>world/NotesList.body 上面代码NoteList组件有两个span子节点,它们都可以通过this.props.children读取,运行结果如下。

这里需要注意,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 { propTypes: { title: React.PropTypes.string.isrequired{ > .title} ; 上面的Mytitle组件有一个title属性PropTypes告诉 React,这个title属性是必须的,而且它的值必须是字符串。现在,我们设置title属性的值是一个数值。

var data = 123<MyTitle title={data这样一来,title属性就通不过验证了。控制台会显示一行错误信息。

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

更多的PropTypes设置,可以查看官方文档

此外,getDefaultProps方法可以用来设置组件属性的默认值。

{ getDefaultProps { title : 'Hello World' <MyTitle 上面代码输出"Hello World"。

七、获取真实的DOM节点

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

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

var MyComponent { handleClick{ this.refs.myTextInputfocus> <input type"text" ref"myTextInput" "button" value"Focus the text input" onClick.handleClick> <MyComponent 上面代码中,组件MyComponent的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个ref属性,然后this.refs.[refName]就会返回这个真实的 DOM 节点。

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

React 组件支持很多事件,除了Click事件以外,还有KeyDownCopyScroll等,完整的事件清单请查看八、this.state

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

var LikeButton { getInitialState{liked: false(eventsetState: !this.state.likedvar text = this.liked ? 'like' 'haven\'t liked'; <p onClick> You {text} this. Click to toggle. <LikeButton 上面代码是一个LikeButton组件,它的getInitialState方法用于定义初始状态,也就是一个对象,这个对象可以通过this.state属性读取。当用户点击组件,导致状态变化,this.setState方法修改状态值,每次修改以后,自动调用this.render方法,再次渲染组件。

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

九、表单

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

var Input {value'Hello!': event.target.valuevar value "text" value} onChange.handleChange(<Input.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):组件判断是否重新渲染时调用
  • 这些方法的详细说明,可以参考官方文档。下面是一个例子(查看demo10)。

    var Hello { opacity: 1.0 .timer = setIntervalvar opacity .opacity; opacity -.05; if (opacity < 0.1{ opacity 1.0; } this{ opacity: opacity ; bind100<div style{{opacity: this> Hello <Hello name"world"上面代码hello组件加载以后,通过componentDidMount方法设置一个定时器,每隔100毫秒,就重新设置组件的透明度,从而引发重新渲染。

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

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

    而要写成

    }

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

    十一、Ajax

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

    var UserGist { username'''' { $get.source(resultvar lastGist = result[0(thisisMounted{ this{ username: lastGist.owner.login.html_url } > .username}'s last gist is <a href.lastGistUrl>here/a<UserGist source"https://api.github.com/users/octocat/gists" 上面代码使用 jQuery 完成 Ajax 请求,这是为了便于说明。React 本身没有任何依赖,完全可以不用jQuery,而使用其他库。

    我们甚至可以把一个Promise对象传入组件,请看Demo12

    @H_119_404@<
    RepoList promise{$getJSON'https://api.github.com/search/repositories?q=javascript&sort=stars'上面代码从Github的API抓取数据,然后将Promise对象作为属性,传给RepoList组件。

    如果Promise对象正在抓取数据(pending状态),组件显示"正在加载";如果Promise对象报错(rejected状态),组件显示报错信息;如果Promise对象抓取数据成功(fulfilled状态),组件显示获取的数据。

    var RepoList { loadingtruenullcomponentDidMount.promisethen( value => this{loading: value: error.loading>Loading..} else .error == >Error.error.messageelse var repos .data.itemsvar repoList = repos(repo{ ( > {repo.html_url.stargazers_count} stars) <br.description} ( <main> >Most Popular JavaScript Projects in Github{repoList/main} ;

    十二、参考链接

    1. React's official site
    2. React's official examples
    3. React (Virtual) DOM Terminology,by Sebastian Markbåge
    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

    猜你在找的React相关文章