一、react入门

一、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入门要了解的概念。

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