ReactNative入门-React基础

本节包含内容有

React背景及特点
创建React应用
开始第一个简单程序 - 运行Hello World
JSX语法入门
组件
Props
state
组件的生命周期

React背景及特点

  • React背景介绍

    在Web应用开发的早期,构建Web应用的唯一方式就是向服务器发送请求,然后服务器响应请求并返回一个完整的页面。从开发角度上讲这种方式非常简单,但是这种开发方式会造成很不好的用户体验,用户的很多行为都需要向服务器请求,等待服务器的反应。因此,开发者开始开发各种类库,使用JavaScript在浏览器端渲染应用。

    React起源于Facebook公司,期初用于Instagram网站开发。React是一个用于构建用户界面的JavaScript库,不是一个MVC框架,提出了一种新的开发模式和理念,它强调的是“用户界面”。

  • React特点

    1.作为UI

    React可以作为MVC中的View层进行使用,并且在已有项目中很容易使用React开发新功能。
    2.虚拟DOM

    虚拟DOM是React最重要的特性,实现了优化视图的渲染和刷新。以前没有Ajax技术的时候,Web页面从服务器端整体渲染出HTML,输出到浏览器端进行渲染,同样的,用户的一个改变页面的操作也会刷新整个页面来完成。知道Ajax的出现,实现页面局部刷新,带来的高效和分离让Web开发者们惊叹不已。但随之而来的问题是复杂的用户交互及展现需要通过大量的DOM操作来完成,这让页面的性能以及开发的效率又出现了新的瓶颈。如何进行高性能的复杂DOM操作通常是衡量一个前端开发人员技能的重要指标。

    时至今日,谈到前端性能优化,减少DOM元素,减少reflow和repaint,编码过程尽量减少DOM的查询等手段是大家耳熟能详的。而页面任何UI的变化都是通过整体刷新来完成的。而React之所以快,是因为它不直接操作DOM,而是引进虚拟DOM的实现来解决这个问题。

    3.组件化

    虚拟DOM(virtual-dom)不仅带来了简单UI开发逻辑,同时也带来了组件化开发的思想。所谓组件,即封装起来的具有独立功能的UI部件。React推荐以组件的方式去重新思考UI构成,将UI上每一个功能相对独立的模块定义出呢个组件,然后将小的组件通过组合或者嵌套的方式构成的大的组件,最终完成整体UI的构建。

    如果说MVC的思想让你做到视图-数据-控制器的分离。那么组件化的思考方式则是带来了UI功能模块之间的分离。

    对于React而言,开发者从功能的角度出发,将UI分成不同的组件,每个组件都独立封装。在React中,你按照界面模块自然划分的方式来组织和编写你的代码。每个组件只关心自己部分的逻辑,彼此独立。React组件应该具有如下特征:可组合、可重用、可维护

    4.数据流

    React实现了单向的数据流,相对于传统的数据绑定,React更加灵活、便捷。

  • React学习准备

    1、前端基础知识:HTML,CSS,JavaScript
    2、JSX语法
    3、ES6相关知识
    4、React中文网站:http://www.css88.com/react/index.html

  • React和ReactNative的关系

    React用于Web用用开发。ReactNative采用React方式进行移动应用开发。
    ReactNative采用React语法,用于进行JavaScript跨终端应用开发,既拥有原生Native的交互体验,又能够保留React自由的开发效率。使用灵活的HTML和CSS布局,使用React语法构建组件,然后同时运行在iOS和Android平台上,“Learn once,write anywhere”

1.创建React应用

使用命令行:

npm install -g create-react-app
create-react-app my-app

在my-app目录下运行npm

cd my-app
npm start

这时候在浏览器中就会显示运行结果,可以在index.js文件下进行修改

整个文件目录是

2.运行Hello World

import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import './index.css';

// React的最基本方法,用于将模板转换成HTML语言,渲染DOM并插入指定的DOM节点
/*
三个参数
第一个:模板的渲染内容(HTML形式)
第二个: 这段模板需要插入的DOM节点,本程序中id为root的div节点
第三个:渲染后的回调,一般不用
*/
ReactDOM.render(
    <h1>Hello World</h1>
    document.getElementById('root')
);

registerServiceWorker();

3.JSX入门

JSX不是一门新的语言,是个语法(语法糖)

  • JSX必须借助React环境运行
  • JSX标签其实就是HTML标签,只不过我们在JavaScript中书写这些标签的时候,不用使用“”括起来
<h1>Hello World</h1> 这就是JSX语法
  • 转换:JSX语法能够让我们更直观的看到组件的DOM结构,不能直接在浏览器上运行,最终会转化成JavaScript代码
// JSX语法书写
ReactDOM.render(
    <h1>
       Hello React
    </h1>,
    document.getElementById('root')
);

// JavaScript语法书写
ReactDOM.render(
    React.createElement("h1", null, "Hello React"),
    document.getElementById('root')
);

两种写法的比较,可以看出来JSX的写法结构很清晰,书写也简单。

  • 如何在JSX中运行JavaScript代码,使用{表达式}括起来,如下边的写法
var text = "世界"
ReactDOM.render(
    <h1>{text}</h1>,
    document.getElementById('root')
);
  • JSX语法在属性、设置样式和事件绑定等中的应用

4.组件

(1)定义组件
创建一个组件类,用于输出Hello React

var HelloMessage = React.createClass({
    render: function () {
      // return <h1>Hello React</h1>;
       // 如果想动态输出内容这里使用属性
        return <h1>{this.props.helloText}</h1>
    }
});

ReactDOM.render(
    // 在模板中插入<HelloMessage />会自动生成一个实例
    <HelloMessage helloText="Hello React"/>,
    document.getElementById('root')
);
  • React中创建的组件类以大写字母开头,驼峰命名法
  • 在React中使用React.creatClass方法创建一个组件类
  • 核心代码:每个组件都必须实现自己的render方法。输出定义好的组件模板。返回值:null,false,组件模板
  • 注意:组件类只能包含一个顶层标签

(2)组件的样式
设置组件的样式: 内联样式,对象样式,选择器样式

注意:在React和HTML5中设置样式时的书写格式是由区别的:
1.HTML5以分号;结尾,React以逗号,结尾
2.HTML5中key、value都不加引号,React中属于JavaScript对象,key的名字不能出现分隔符“-”,需要使用驼峰命名法,
如果value为字符串,需要加引号。
3.HTML5中,value如果是数字需要带单位,React中不需要带单位

定义一个组件类,同时使用三种设置组件样式的方式。div使用内联样式:设置背景颜色,边框大小,边框颜色;h1使用对象样式:设置背景颜色,字体颜色;p使用选择器样式:设置字体大小

var ShowMessage = React.createClass({
    render: function() {
        return (
            <div style={{backgroundColor:"yellow", borderWidth: 5, borderColor:"black", borderStyle:"solid"}}>
                <h1 style={hStyle}>{this.props.firstRow}</h1>
                // 在React中使用选择器样式设置组件样式时,属性名不能使用class,需要使用className替换。同样的还有使用htmlFor替换for
                <p className="pStyle">{this.props.secondRow}</p>
            </div>
        )
    }
});

// 创建设置h1样式对象Name
var hStyle = {
    backgroundColor: "green",
    color: "red"
}

ReactDOM.render(
    <ShowMessage firstRow="你好" secondRow="小明"/>,
    document.getElementById('root')
);

这里p使用的是选择样式,将样式写在index.css中,在使用的过程中进行导入

import './index.css';

.pStyle {
  font-size: 20px;
}

在React中使用选择器样式设置组件样式时,属性名不能使用class,需要使用className替换。同样的还有使用htmlFor替换for

(3)复合组件

复合组件 也称为组合组件,创建多个组件合成一个组件。定义一个组件的WebShow。功能:输出网站的名字和网址,网址是一个可以点击的链接。

分析:定义一个组件WebName负责输出网站名字,定义组件WebLink显示网站的网址,并且可以点击

// 定义WebName组件
var WebName = React.createClass({
    render: function() {
        return (
            <h1>{this.props.webName}</h1>
        )
    }
});

// 定义WebLink组件
var WebLink = React.createClass({
    render: function() {
        return (
             <a href={this.props.webLink}>{this.props.webLink}</a>
        )
    }
});

// 组合组件WebShow
var WebShow = React.createClass({
    render: function() {
        return (
            <div>
                <WebName webName={this.props.webName}/>
                <WebLink webLink={this.props.webLink}/>
            </div>
        )
    }
});


ReactDOM.render(
    <WebShow webName="新浪" webLink="http://www.sina.com.cn"/>,
    document.getElementById('root')
);

5.props

props是组件自身的属性,一般用于嵌套的内外层组件中,负责传递数据(通常是由父层向子层组件传递)

注意:props对象中的属性与组件的属性一一对应,不要直接直接去修改props中属性的值

...this.props

这个是props提供的语法糖,可以将父组件中的全部属性都复制给子组件

下边定义一个Link组件,Link组件只包含一个<a>,我们不给<a>设置任何属性,所有属性全部从父组件复制得到

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

ReactDOM.render(
    <Link href="http://www.baidu.com" name="百度" />,
    document.getElementById("root")
)

this.props.children

children组件是一个例外,不是跟组件的属性对应的,它表示组件的所有子节点

下边展示一种列表,在HTML5中有一种标签:<ul> <ol> <li>。定义一个列表组件,列表项中显示的内容,以及列表项的数量都由外部决定。

var ListComponent = React.createClass({
    render: function () {
        return (
            <ul>
                {
                    // 列表项数量不确定,在创建模板时才能确定,利用this.props.children从父组件获取需要展示的列表项内容
                    // 获取到列表项内容后,需要遍历children,逐行进行设置
                    // 使用React.Children.map方法 返回值:数组对象,这里数组中的元素是<li>
                    React.Children.map(this.props.children, function (child) {
                        // child是遍历得到的父组件的子节点
                        return <li>{child}</li>
                    })
                }
            </ul>
        );
    }
});

ReactDOM.render(
    (
        <ListComponent>
            <h1>百度文库</h1>
            <a href="http://www.baidu.com">http://www.baidu.com</a>
            <h1>百度文库</h1>
            <a href="http://www.baidu.com">http://www.baidu.com</a>
            <h2>百度文库</h2>
         </ListComponent>
    ),
    document.getElementById("root")
);

属性验证

用来验证外部设置的值是否符合组件对属性类型的要求,也是组件类的属性。用来验证组件实例的属性是否符合要求

var ShowTitle = React.createClass({
    // 属性验证
    propTypes: {
        // title 必须为字符串
        title: React.PropTypes.string.isRequired
    },
    render: function () {
        return <h1>{this.props.title}</h1>
    }
});

ReactDOM.render(
    // 这里如果传入title=1234,运行就会出错,因为属性验证要求组件传入的属性时字符串类型的
    <ShowTitle title="1234"/>,
    document.getElementById("root")
);

设置组件属性的默认值

通过实现组件的getDefaultProps方法,对属性设置默认值

var ShowTitle = React.createClass({
    getDefaultProps: function () {
        return {
            title: "小明"
        }
    },
    
    render: function () {
        return <h1>{this.props.title}</h1>
    }
});

ReactDOM.render(
    // 这里虽然没有传入属性值,但是属性设置了默认值,因此渲染结果是显示出“小明”字样
    <ShowTitle />,
    document.getElementById("root")
);

6.state

事件处理
定义一个组件,组件中包含一个button,给button绑定onClick事件

var MyButton = React.createClass({
    // React中的事件名称,首字母小写,驼峰命名法
    handleClick: function () {
        alert("点击按钮触发的效果")
    },

    render: function () {
        return <button onClick={this.handleClick}>{this.props.buttonTitle}</button>
    }
});

ReactDOM.render(
    <MyButton buttonTitle="按钮" />,
    document.getElementById("root")
);

state状态
state和props一样,都是组件自身的属性,通过调用this.state

下边创建一个CheckButton组件,包含一个checkbox类型的<input>,复选框在选中和未选中两种状态下会显示不同的文字,即根据状态渲染

var CheckButton = React.createClass({
    // 定义初始状态
    getInitialState: function () {
        return {
            // 在这个对象中设置的属性,将会存储在state中
            isCheck: false
        }
    },

    // 定义事件绑定的方法
    handleChange: function () {
        // 修改状态值,通过this.state读取设置的状态值
        this.setState({
            isCheck: !this.state.isCheck
        });
    },

    render: function () {
        // 根据状态值,设置显示的文字
        // 注意: 在JSX中不能直接使用if, 如果需要条件判断需要在外边写个方法将结果传进来就行,可以使用三目运算符
        var text = this.state.isCheck ? "已选中" : "未选中";
        return (
            // 返回结果只能有一个根节点
            <div>
                <input type="checkbox" onChange={this.handleChange} />
                {text}
            </div>
        );
    }
});

ReactDOM.render(
    <CheckButton />,
    document.getElementById("root")
);

注意:
当state发生变化时,会调用组件内部的render方法

表单的基本使用

定义一个组件,将用户在输入框内输入的内容进行实时显示。组件在于用户的交互过程中,存在状态的变化,即输入框的值

var Input = React.createClass({
    getInitialState: function () {
            return {
                value: "请输入"
            };
    },

    // 输入框的输入回传进来一个参数event
    handeleChange: function (event) {
        // 通过event.target.value读取用户输入的值
        this.setState({
            value: event.target.value
        });
    },

    render: function () {
        var value = this.state.value;
        return(
            <div>
                <input type="text" value={value} onChange={this.handeleChange} />
                <p>{value}</p>
            </div>
        );
    }
});

ReactDOM.render(
    <Input />,
    document.getElementById("root")
);

7.组件的生命周期

生命周期介绍

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

  • Mounting:组件挂载,已插入真实的DOM
  • Updating:组件更新,正在被重新渲染
  • Unmounting: 组件移出,已移出真实DOM

组件的生命周期可分成四个阶段:创建、实例化、更新、销毁

每种状态对应的方法:

  • Mounting/组件挂在相关:

    • componentWillMount:组件将要挂载。在render方法之前执行,但仅执行一次,即使多次重复渲染该组件,或者改变了组件的state
    • componentDidMount:组件已经挂在。在render之后执行,同一个组件重复渲染只执行一次
  • Updating/组件更新相关:

    • componentWillReceiveProps(object nextProps):已加载组件收到新的props之前调用,注意组件初始化渲染时不会执行
    • shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用。该接口实际是在组件接收到了新的props或者新的state的时候会立即调用。返回一个Bool值。默认情况下是ture,这就是为什么在前文中说只要调用this.setState方法,就会重新渲染。当返回结果为true时会立即调用下边另外两个方法,如果返回false,则不会进行更新。
    • componentWillUpdate(object nextProps, object nextState):组件将要更新
    • componentDidUpdate(object prevProps, object prevState):组件已经更新
  • Unmounting/组件移除相关:

    • componentWillUnmount:在组件要被移除之前的时间点触发,可以利用该方法来执行一些必要的清理组件相关的工作
  • 生命周期中与props和state相关:

    • getDefaultProps 设置props属性默认值
    • getInitialState 设置state属性初始值

生命周期各阶段介绍

  • 一、创建阶段流程:
    • 只调用getDefaultProps方法
  • 二、实例化阶段流程:
    • getInitialState
    • componentWillMount
    • render
    • componentDidMount
  • 三、更新阶段流程:
    • componentWillReceiveProps
    • shouldComponentUpdate 如果返回值是false,后三个方法不执行
    • componentWillUpdate
    • render
    • componentDidUpdate
  • 四、销毁阶段流程:
    • 流程:componentWillUnmount
var Demo = React.createClass({
    /*
        一、创建阶段
        流程:只调用getDefaultProps方法
    */
    getDefaultProps: function () {
            // 正在创建类的时候被调用,设置this.props的默认值
            console.log("getDefaultProps");
            return {};
    },

    /*
        二、实例化阶段
        流程: getInitialState
                    componentWillMount
                    render
                    componentDidMount
    */
    getInitialState: function () {
        // 设置this.state的默认值
        console.log("getInitialState");
        return null;
    },
    componentWillMount: function () {
        // 在render之前调用
        console.log("componentWillMount");
    },
    render: function () {
        // 渲染并返回一个虚拟的DOM
        console.log("render");
        return <div>Hello React</div>
    },
    componentDidMount: function () {
        // 在render之后调用 在该方法中,React会使用render方法返回的虚拟DOM对象创建真实的DOM结构
        // 可以在这个方法中读取DOM节点
        console.log("componentDidMount");
    },

    /*
        三、更新阶段
        流程:componentWillReceiveProps
                 shouldComponentUpdate  如果返回值是false,后三个方法不执行
                 componentWillUpdate
                 render
                 componentDidUpdate
    */
    componentWillReceiveProps: function () {
        console.log("componentWillReceiveProps");
    },
    shouldComponentUpdate: function () {
        console.log("shouldComponentUpdate");
        return true;
    },
    componentWillUpdate: function () {
        console.log("componentWillUpdate");
    },
    componentDidUpdate: function () {
        console.log("componentDidUpdate");
    },

    /*
        四、销毁阶段
        流程:componentWillUnmount
    */
    componentWillUnmount: function () {
        console.log("componentWillUnmount");
    }
});

// 第一次创建并加载组件
ReactDOM.render(
    <Demo />,
    document.getElementById("root")
);
/*
    上边结果返回的是:
    getDefaultProps
    getInitialState
    componentWillMount
    render
    componentDidMount
*/

// 更新渲染组件
ReactDOM.render(
    <Demo />,
    document.getElementById("root")
);
/*
    更新渲染后的结果:
    componentWillReceiveProps
    shouldComponentUpdate
    componentWillUpdate
    render
    componentDidUpdate

    注意如果将shouldComponentUpdate的返回值设置成false,那么该方法以下的步骤将不会再执行
    返回结果是:
    componentWillReceiveProps
    shouldComponentUpdate
*/

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

推荐阅读更多精彩内容

  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,808评论 1 18
  • 深入JSX date:20170412笔记原文其实JSX是React.createElement(componen...
    gaoer1938阅读 8,037评论 2 35
  • 自己最近的项目是基于react的,于是读了一遍react的文档,做了一些记录(除了REFERENCE部分还没开始读...
    潘逸飞阅读 3,322评论 1 10
  • springboot上传文件大小的配置我这里记录两种,一种是设置在配置文件里只有两行代码,一种是加个Bean 首先...
    loserStar阅读 2,676评论 0 0
  • 为自己健康做定投,身体是自己的,钱没有可以赚。 当身体出现各种疾病,有钱不一定好用。 每天坚持快走10公里,风雨无...
    一个落魄老男人阅读 536评论 0 0