美文网首页
ReactNative入门-React基础

ReactNative入门-React基础

作者: 寒桥 | 来源:发表于2017-06-26 23:47 被阅读56次

    本节包含内容有

    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
    */
    

    相关文章

      网友评论

          本文标题:ReactNative入门-React基础

          本文链接:https://www.haomeiwen.com/subject/msrscxtx.html