美文网首页
一、react入门

一、react入门

作者: liquan_醴泉 | 来源:发表于2019-02-14 22:20 被阅读0次

    一、react的基本概念

    1.1 react的定义:
        根据官方文档介绍,react是一个只关注用户界面的js库(说白了就是将数据渲染成页面的一个js库),关于js库我们并不陌生,如jquery。当然学习react只学习react.js是不够的,还要学习他的衍生物,如react-router,redux等等,他们组合在一起被称作为react全家桶或者技术栈。
    1.2 react的特点:

        根据官方文档介绍,react有一下特点:如图 QQ图片20190212231701.png

        1.2.1 声明式,所谓的声明式就好比,在之前用jquery时我们需要操作dom,很费劲,而声明式就可以做到你告诉react我们要更新dom,让react去操作,我们只需要告诉他就行,即为应用的每一个状态设计简洁的视图,在数据改变时react也可以高效的更新界面。因此我们只要更新数据,就可以得到我们想要的界面。
        1.2.2 组件化,组件化就是将独立的功能抽离出去当作一个组件,最后将这些组件组合到一起形成一个系统,每个组件都有其特定的内部状态。
        1.2.3 一次学习,随处编写,是因为react不仅可以编写web应用,还可以编写native应用叫做react-native,编写的程序可以运行在手机上)。
        1.2.4 高效,react是高效率的,就其原因有,他采用虚拟dom技术,不是直接操作dom,这样可以减少更新的次数。其次是dom diff算法,最小化页面的重新绘制,这样可以减少更新的区域。
        1.2.5 单向数据流,此概念较抽象,后面会逐渐解析到

    二、react的基本用法(此法只是为了了解react的基本用法,真实项目中不会这么用)

    2.1 通过前面的了解,我们知道了react是一个js库,既然是一个js库,我们只要通过script标签引入便可以使用它,可以通过cdn的方式引入,下面根据官方文档示例简单体会一下react的神奇之处。如图,用jsx来编码 image.png
    ,新建一个项目,结构如下: QQ图片20190213230035.png
    打开浏览器,可以看到如下结果:虚拟dom被渲染到真实dom中了。 image.png ,上面引入了三个库,一个是react的核心库,一个是react-dom是基于react的一个专门操作dom的扩展库。一个是babel库,用于将jsx(是js的扩展语法)代码转为js代码。

    三、虚拟dom

    react提供了创建虚拟dom的方法React.createElement, 例如创建一个虚拟h1,React.createElement('h1', {id: 'myTitle'}, 'hello react'),如下面的代码:

    <!DOCTYPE html>
    <html lang="en" dir="ltr">
      <head>
        <meta charset="utf-8">
        <title>react-demo1</title>
      </head>
      <body>
        <div id="root">
    
        </div>
        <div id="test">
    
        </div>
        <!--react的核心库-->
        <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <!--是基于react的专门操作dom的扩展库-->
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    
        <!-- Don't use this in production: -->
        <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    
        <script type="text/javascript">
          var msg = 'hello React'
          var msgId = "Box"
    
          const vDom1 = React.createElement('h1', {id: msgId.toUpperCase()}, msg.toLowerCase())
    
          ReactDOM.render(vDom1, document.getElementById('root'))
        </script>
    
        <script type="text/babel">
          var msg = 'hello React'
          var msgId = "Box"
          const vDom2 = <h3 id={msgId.toLowerCase()}>{msg.toUpperCase()}</h3> // 这是jsx的语法,用起来简单,但最终还是成React.createElement执行
          // 这里虚拟dom的h3最终会转化为真实dom的h3, 也就是说虚拟dom和真实dom是一一对应的。
          var realDom = document.getElementById('test')
          debugger
          ReactDOM.render(vDom2, document.getElementById('test'))
        </script>
      </body>
    </html>
    
    
    分别用创建虚拟dom的方式和jsx的方式进行react的渲染,都可以将创建的标签渲染到页面中,其实jsx的方式最终也是转化为了React.createElement来执行的。如下: image.png

    那么虚拟dom和真实dom有啥样的关系?首先创建一个最简单的虚拟dom,

    const vDom = React.createElement('h1', {id: 'title'}, 'react技术栈')
    console.log(vDom ) // 得到如下属性:
    
    {$$typeof: Symbol(react.element), type: "h1", key: null, ref: null, props: {…}, …}
    $$typeof: Symbol(react.element)
    key: null
    props: {id: "title", children: "react技术栈"}
    ref: null
    type: "h1"
    _owner: null
    _store: {validated: false}
    _self: null
    _source: null
    __proto__: Object
    
    // 其次获取一个真实的dom,
    const div = document.getElementById('box)
    可以得到div dom对象的属性如下:
    accessKey: ""
    align: ""
    assignedSlot: null
    attributeStyleMap: StylePropertyMap {size: 0}
    attributes: NamedNodeMap {0: id, id: id, length: 1}
    autocapitalize: ""
    baseURI: "file:///C:/Users/nan/Desktop/react-demo1/index.html"
    childElementCount: 0
    childNodes: NodeList [text]
    children: HTMLCollection []
    classList: DOMTokenList [value: ""]
    className: ""
    clientHeight: 0
    clientLeft: 0
    clientTop: 0
    clientWidth: 472
    contentEditable: "inherit"
    dataset: DOMStringMap {}
    dir: ""
    draggable: false
    firstChild: text
    firstElementChild: null
    hidden: false
    id: "test"
    innerHTML: "↵↵    "
    innerText: ""
    inputMode: ""
    isConnected: true
    isContentEditable: false
    lang: ""
    lastChild: text
    lastElementChild: null
    localName: "div"
    namespaceURI: "http://www.w3.org/1999/xhtml"
    nextElementSibling: script
    nextSibling: text
    nodeName: "DIV"
    nodeType: 1
    nodeValue: null
    nonce: ""
    offsetHeight: 0
    offsetLeft: 8
    offsetParent: body
    offsetTop: 85
    offsetWidth: 472
    onabort: null
    onauxclick: null
    onbeforecopy: null
    onbeforecut: null
    onbeforepaste: null
    onblur: null
    oncancel: null
    oncanplay: null
    oncanplaythrough: null
    onchange: null
    onclick: null
    onclose: null
    oncontextmenu: null
    oncopy: null
    oncuechange: null
    oncut: null
    ondblclick: null
    ondrag: null
    ondragend: null
    ondragenter: null
    ondragleave: null
    ondragover: null
    ondragstart: null
    ondrop: null
    ondurationchange: null
    onemptied: null
    onended: null
    onerror: null
    onfocus: null
    ongotpointercapture: null
    oninput: null
    oninvalid: null
    onkeydown: null
    onkeypress: null
    onkeyup: null
    onload: null
    onloadeddata: null
    onloadedmetadata: null
    onloadstart: null
    onlostpointercapture: null
    onmousedown: null
    onmouseenter: null
    onmouseleave: null
    onmousemove: null
    onmouseout: null
    onmouseover: null
    onmouseup: null
    onmousewheel: null
    onpaste: null
    onpause: null
    onplay: null
    onplaying: null
    onpointercancel: null
    onpointerdown: null
    onpointerenter: null
    onpointerleave: null
    onpointermove: null
    onpointerout: null
    onpointerover: null
    onpointerup: null
    onprogress: null
    onratechange: null
    onreset: null
    onresize: null
    onscroll: null
    onsearch: null
    onseeked: null
    onseeking: null
    onselect: null
    onselectstart: null
    onstalled: null
    onsubmit: null
    onsuspend: null
    ontimeupdate: null
    ontoggle: null
    onvolumechange: null
    onwaiting: null
    onwebkitfullscreenchange: null
    onwebkitfullscreenerror: null
    onwheel: null
    outerHTML: "<div id="test">↵↵    </div>"
    outerText: ""
    ownerDocument: document
    parentElement: body
    parentNode: body
    prefix: null
    previousElementSibling: div#root
    previousSibling: text
    scrollHeight: 0
    scrollLeft: 0
    scrollTop: 0
    scrollWidth: 472
    shadowRoot: null
    slot: ""
    spellcheck: true
    style: CSSStyleDeclaration {alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: "", …}
    tabIndex: -1
    tagName: "DIV"
    textContent: "↵↵    "
    title: ""
    translate: true
    __proto__: HTMLDivElement
    

    通过对比,很明显的知道虚拟dom对象要比真实dom轻量很多。虚拟dom只有很少的属性。而且真实dom的更改都会引起页面的重绘,而虚拟dom在渲染在真实dom之前是不会重绘页面的,这就是虚拟dom高效的原因。

    四,jsx(全称为javascript xml)

    • 首先jsx是一种语法,是react定义的一种类似与xml的js扩展语法:xml + js
    • 作用: 用来创建react虚拟dom元素对象,之前就提到过,最终会转化为React.createElement执行,他的特点如下:

        1.标签名任意(不仅可以写html的标签,而且还可以自定义标签),比如:

    const vDom = <div>你好 react</div> // 这种写法不能加单引号或者双引号,最终产生的是一个对象
    const vDom2 = <MyReact></MyReact> // 这种标签叫做组件标签
    

        2.标签属性任意(HTML标签属性或者其他属性)

        3.语法规则(遇到< 开头的代码,以标签的语法解析:html同名标签转为html同名元素其他标签需要特别解析。遇到{ 开头的代码以js语法解析,标签中的js代码必须用{}包含)
    通过以上的了解,这里做一个简单的示例:(动态的展示列表数据)

    <!DOCTYPE html>
    <html lang="en" dir="ltr">
      <head>
        <meta charset="utf-8">
        <title>react-demo1</title>
      </head>
      <body>
        <div id="root">
    
        </div>
    
        <!--react的核心库-->
        <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <!--是基于react的专门操作dom的扩展库-->
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    
        <!-- Don't use this in production: -->
        <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    
        <script type="text/babel">
    
          /**
          * 有几个问题:
          *  1.展示一个列表,那么数据结构应为list,这里定义一个名为persons的数组作为list
          *  2. 如何将数据的数组转化为标签的数组? 利用数组的map方法,map可以由返回值组成一个新的数组
          *  3. react要求列表数据需要一个唯一的key
          */
          // 定义列表数据
          let persons = ['唐僧','孙悟空', '猪八戒', '沙参']
    
          // 创建虚拟dom,列表用ul li来呈现
          // 注意,一旦有嵌套的标签就用()包含
          const ul = (
              persons.map((name, index) => <li key={index}>{name}</li>)
          )
          // 将虚拟dom渲染到真实dom中
          ReactDOM.render(ul, document.getElementById('root'))
        </script>
    
      </body>
    </html>
    
    

    得到的效果如下:


    image.png

    从以上的这个例子可以得出几个问题,1. 需要什么样的数据结构,2.如何将数据转化为标签数据。

    五,模块与组件,模块化与组件化

    1.模块:向外提供提供特定功能的js程序,一般一个 js 文件就是一个模块(一般模块内部有数据,简单理解就是变量,和对数据的操作,简单理解就是函数),模块可以达到复用js,简化js的编写,提高js的运行效率。

    1. 组件: 用来实现特(局部)功能效果的代码集合(html,css,js),简单说就是一个界面的局部功能模块,既然是界面功能,那么就必须包含html/css/js三要素

    3.模块化: 就是指在编写项目的时候是不是以模块的方式编写的,是,就是模块化项目,不是,就不算模块化项目

    1. 组件化: 形容项目的编码方式,一个项目是由各个组件组合而成,则这个项目就是组件化项目。

    以上就是react入门要了解的概念。

    相关文章

      网友评论

          本文标题:一、react入门

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