React初识

React是一个JavaScript语言的工具库,起源于Facebook的一个内部项目,最初用来构建Instagram的网站,并于2013年5月开源。

安装

对于React初学者而言,React官方提供了一个工具——create-react-app,目的是将开发者人员从配置中解放出来,从而能快速的进入到React应用的开发中。

具体安装过程如下:


npm install -g create-react-app   全局安装 creat-react-app 命令

create-react-app   my-app          使用命令在当前目录下创建一个名为my-app的react应用

cd my-app                                   进入my-app项目文件夹

npm-start                                     执行该命令


之后会启动一个开发者模式的服务器,同时浏览器自动打开一个网页,指向http://localhost:3000/

界面如下图所示:

http://localhost:3000/

第一个React应用就这样诞生了~

生成的文件夹目录结构,如下图所示:


项目目录结构

开发过程中,我们主要关注src目录中的内容,而我们所创建项目的入口便是src/index.js文件,这里面的代码做了这样一件事,它渲染了一个名为App的组件,将其挂在到了id为root的DOM节点上。

src/index.js

同时我们再来看看在src/App.js中,App组件是怎样创建的:

src/App.js

可以看到代码的第一行我们从react库中引入了React和Component,Component作为所有组件的基类,提供了很多组件共有的功能,之后创建了一个名为App的组件类,然后通过export default App将其导出,并在在src/index.js中通过import导入,最后加以使用。

UI=render(data)

React的理念归结为一个公式:UI=render(data)

用户看到的UI界面,是一个函数——render的执行结果,只接受数据——data作为参数。这是一个纯函数,即输出只依赖于输入的函数,两次函数的调用如果输入相同,那么输出也绝对相同。如此一来,最终的用户界面,在render函数确定的情况下完全取决于输入数据。

因此对于开发者而言,重要的是区分,哪些是render,哪些是data,想要改变UI,要做的就是更新data

——《深入浅出React和Redux》

Virtual DOM

在上一节中,我们似乎很容易得出这样一个结论,每次更新UI界面,react都要进行重新渲染,这样会不会使得效率低下呢?

事实上并不会这样,React利用Virtual DOM让每次渲染都只渲染最少的DOM元素。Virtual DOM是对DOM树的抽象,它并不触及浏览器部分,只是存在于JavaScript空间的树形结构,每次在渲染React组件,React会对前后两次产生的Virtual DOM进行比较,最后只有发生了改变的地方会被重新渲染。

总而言之,React利用函数式编程的思维来解决用户界面渲染的问题,强制所有组件都以数据驱动渲染的模式进行开发。

JSX

要学习react首先就要了解JSX,它是JavaScript的一种扩展语法,使我们能够在JavaScript中编写类似HTML的代码。

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

我们可以用{}将任意的JavaScript表达式嵌入到JSX中。

JSX注释也很简单,一般用花括号包围:


{/* 这里是注释 */}


React组件

React允许将代码封装成组件,然后像插入普通HTML标签那样,插入使用我们自定义的组件。自定义的组件要以大写字母开头,这样才能被识别为React组件。

组件也可以在标签中插入任意属性,特别注意:

class属性需要写成className,for属性需要写成htmlFor,这是因为class和for是 JavaScript 的保留字。对于属性的访问,可以通过this.props.xxx来访问对应的xxx属性。

每个组件必须有一个render方法,用于输出组件自身,同时输出的组件只能包含一个顶层标签。

举个例子:

名为Demo的组件

在上面的例子中,我们创建了一个名为Demo的React组件,用来在界面输出Hello,my name is xxx的信息。而this.props.name就是对组件调用时传入的name属性的访问。最终界面输出如下图所示:

输出结果

props & state

React组件的数据分为两种——props和state。其中props是组件的对外接口,state则是组件的内部状态。它们任何一个的改变都会引发组件的重新渲染。

props

props是从外部传递给组件的数据,在上一节的例子中,name就是传递给Demo组件的一个外部props,同时在组件内部,通过this.props.nam访问,这样我们就能很轻易的将外部的数据传递给组件内部。那相反,如果我们想要把内部的数据传递给外部该怎么办呢?

同样也是使用props,因为props的类型不限于纯数据,它还可以是函数,所以我们可以定义一个函数类型的props,相当于父组件交给了自组件一个回调函数。自组件在适当的时候调用这个函数,并传入必要的参数,父组件接收到参数后,对参数进行相应的逻辑处理。

举个例子:

Parent父组件

在Parent父组件中,我们定义了一个changeResult的函数,它接收一个参数,最后计算出参数的二次幂,将结果result显示在界面中。同时,接收的这个参数是来自于Child组件,父组件在调用子组件时,将changeValue这个方法作为子组件的props传给了子组件。

Child子组件

在Child子组件中,点击button会使得子组件中value值加1,并在此时调用this.props.changeValue,将新的value值传给父组件Parent。

最终的效果如下图所示:

初始值
点击button后的值

protoType可以用来规范组件的接口,定义自己可以接收哪些类型或者符合哪些规则的prop。以上面的Child组件来说,我们要求它接收的changeReault是一个函数:


Child.propTypes = {

changeResult: PropTypes.func

};


上面的代码要求changeResult这个prop必须是个函数的类型。


state

state代表组件的内部状态,因为组件不能修改传入的props,所以为了记录自身的状态变化就得用到state。

组件的state通常在组件的构造函数中初始化,且state必须是一个对象。


constructor(props){

    super(props);

    this.state = {

        value: 0

    }

}


React还提供了一个defaultProps功能,用来制定默认的prop值,在特定的props值不是必须且没有被传入的情况下,会使用这个指定的默认值。


Child.defaultProps = {

    changeResult: f => f      //默认是一个什么都不做的函数

}


对state的修改不能直接通过this.state.xxx来修改,需要调用this.setState({xxx: newValue});来修改。因为this.setState会驱动组件进行重新渲染,而如果直接用this.state.xxx来修改,并不能触发。

React组件的生命周期

React定义了组件的生命周期,可分为一下三个过程:


装载过程:Mount —— 组件第一次在DOM树中渲染的过程

更新过程:Update —— 组件被重新渲染的过程

卸载过程:Unmount —— 组件从DOM中删除的过程


在不同的生命周期中,React会一次调用组件的一些函数,这些函数被称为生命周期函数。

装载过程

当组件第一次被挂载的时候会依次调用以下函数:


constructor

componentWillMount

render

componentDidMount


这几个函数从函数名就大概知道是什么了。

constructor构造函数,非必需,无状态组件可以不使用。在存在的情况下,constructor是生命周期中被调用的第一个函数,在这里我们可以初始化state,同时绑定成员函数的this环境。

componentWillMount,非必需,render函数之前被调用,与componentDidMount对称。同时componentWillMount可以在服务端和浏览器端被调用。

render,必须,它是React组件中最重要的函数,它返回一个JSX描述的结构,之后React来操作渲染过程,render函数是一个纯函数,完全根据this.state和this.props 来决定返回结果,因此在render函数中调用this.setState是错误的。

componentDidMount,非必需,只能在浏览器端被调用,componentDidMount函数并不是紧跟render函数后面被调用,它被调用时,render函数返回的东西已经引发来渲染,组件已经被“装载”到了DOM树上,此时可以放心的获取渲染出来的任何DOM,也可以通过ajax获取数据来填充组件的内容。

更新过程

更新过程会调用如下生命周期函数:


componentWillReceiveProps

shouldComponentUpdate

componentWillUpdate

render

componentDidUpdate


但并不是所有更新过程都会调用以上所有函数。

我们先来看看哪些情况会触发更新过程(默认shouldComponentUpdate返回true)

1. 父组件的render函数被调用

2. this.setState调用,但不是每调用一次就更新一次,有时react会合并操作,并最后一次性调用render更新

3. this.forceUpdate强制更新

而在这些情况下会依次调用的生命周期函数,如下图所示:

更新路径

componentWillReceiveProps当父组件调用render时会触发,而不是仅仅只有props发生改变时才触发。

shouldComponentUpdate默认返回true,如果返回false则立即停止更新,如果恰当使用shouldComponentUpdate来控制是否继续更新,可以有效提高效率。

componentWillUpdate,当shouldComponentUpdate返回true,紧接着调用componentWillUpdate,之后是render,再之后是componentDidUpdate。

注意:通过this.setState函数引发的更新,并不是立刻改变state的值,其实,在调用shouldComponentUpdate时state的值依然是this.setState执行之前的值。

卸载过程

componentWillUnmount,当react组件需要从DOM树上删除掉之前会调用它,所以这个函数适合做一些清理工作。比如,在componentDidMount中用非react的方法创造了一些DOM元素,如果撒手不管的话会造成内存泄漏,那就需要在componentWillUnmount中将这些DOM卸载掉。

参考文章和书籍

http://www.jianshu.com/p/4784216b8194

《深入浅出React和Redux》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,192评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,186评论 1 303
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,844评论 0 252
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,471评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,876评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,891评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,068评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,791评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,539评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,772评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,250评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,577评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,244评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,146评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,949评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,995评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,812评论 2 276

推荐阅读更多精彩内容

  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,771评论 1 18
  • 深入JSX date:20170412笔记原文其实JSX是React.createElement(componen...
    gaoer1938阅读 7,984评论 2 35
  • 做React需要会什么? react的功能其实很单一,主要负责渲染的功能,现有的框架,比如angular是一个大而...
    苍都阅读 14,700评论 1 139
  • 体验入:早晨听到同事们说了一句“再传递负能量就上报组织”,虽然听着是玩笑话但是说明大家都在用心的学习了 找核心:学...
    Tracy_zhang阅读 171评论 0 3
  • 这只是只言片语, 哪能道得出来, 萤火虫在夜空起舞, 夜莺却停止了啼叫, 那远逝的身影, 眼角的泪, 是为你的送行...
    爱吃肉的和尚阅读 168评论 0 1