一、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去操作,我們只需要告訴他就行,即為應用的每一個狀態(tài)設計簡潔的視圖,在數據改變時react也可以高效的更新界面。因此我們只要更新數據,就可以得到我們想要的界面。
????1.2.2 組件化,組件化就是將獨立的功能抽離出去當作一個組件,最后將這些組件組合到一起形成一個系統,每個組件都有其特定的內部狀態(tài)。
????1.2.3 一次學習,隨處編寫,是因為react不僅可以編寫web應用,還可以編寫native應用叫做react-native,編寫的程序可以運行在手機上)。
????1.2.4 高效,react是高效率的,就其原因有,他采用虛擬dom技術,不是直接操作dom,這樣可以減少更新的次數。其次是dom diff算法,最小化頁面的重新繪制,這樣可以減少更新的區(qū)域。
????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提供了創(chuàng)建虛擬dom的方法React.createElement, 例如創(chuàng)建一個虛擬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執(zhí)行
      // 這里虛擬dom的h3最終會轉化為真實dom的h3, 也就是說虛擬dom和真實dom是一一對應的。
      var realDom = document.getElementById('test')
      debugger
      ReactDOM.render(vDom2, document.getElementById('test'))
    </script>
  </body>
</html>

分別用創(chuàng)建虛擬dom的方式和jsx的方式進行react的渲染,都可以將創(chuàng)建的標簽渲染到頁面中,其實jsx的方式最終也是轉化為了React.createElement來執(zhí)行的。如下:
image.png

那么虛擬dom和真實dom有啥樣的關系?首先創(chuàng)建一個最簡單的虛擬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
  • 作用: 用來創(chuàng)建react虛擬dom元素對象,之前就提到過,最終會轉化為React.createElement執(zhí)行,他的特點如下:

????1.標簽名任意(不僅可以寫html的標簽,而且還可以自定義標簽),比如:

const vDom = <div>你好 react</div> // 這種寫法不能加單引號或者雙引號,最終產生的是一個對象
const vDom2 = <MyReact></MyReact> // 這種標簽叫做組件標簽

????2.標簽屬性任意(HTML標簽屬性或者其他屬性)

????3.語法規(guī)則(遇到< 開頭的代碼,以標簽的語法解析:html同名標簽轉為html同名元素其他標簽需要特別解析。遇到{ 開頭的代碼以js語法解析,標簽中的js代碼必須用{}包含)
通過以上的了解,這里做一個簡單的示例:(動態(tài)的展示列表數據)

<!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 = ['唐僧','孫悟空', '豬八戒', '沙參']

      // 創(chuàng)建虛擬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入門要了解的概念。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容