溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

React的相關(guān)知識(shí)點(diǎn)有哪些

發(fā)布時(shí)間:2022-01-14 17:40:54 來(lái)源:億速云 閱讀:156 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“React的相關(guān)知識(shí)點(diǎn)有哪些”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“React的相關(guān)知識(shí)點(diǎn)有哪些”文章能幫助大家解決問題。

React與傳統(tǒng)MVC的關(guān)系

輕量級(jí)的視圖層庫(kù)!A JavaScript library for building user interfaces

React不是一個(gè)完整的MVC框架,最多可以認(rèn)為是MVC中的V(View),甚至React并不非常認(rèn)可MVC開發(fā)模式;React 構(gòu)建頁(yè)面 UI 的庫(kù)。可以簡(jiǎn)單地理解為,React 將將界面分成了各個(gè)獨(dú)立的小塊,每一個(gè)塊就是組件,這些組件之間可以組合、嵌套,就成了我們的頁(yè)面。

React高性能的體現(xiàn):虛擬DOM

React高性能的原理:

在Web開發(fā)中我們總需要將變化的數(shù)據(jù)實(shí)時(shí)反應(yīng)到UI上,這時(shí)就需要對(duì)DOM進(jìn)行操作。而復(fù)雜或頻繁的DOM操作通常是性能瓶頸產(chǎn)生的原因(如何進(jìn)行高性能的復(fù)雜DOM操作通常是衡量一個(gè)前端開發(fā)人員技能的重要指標(biāo))。

React為此引入了虛擬DOM(Virtual DOM)的機(jī)制:在瀏覽器端用Javascript實(shí)現(xiàn)了一套DOM API?;赗eact進(jìn)行開發(fā)時(shí)所有的DOM構(gòu)造都是通過(guò)虛擬DOM進(jìn)行,每當(dāng)數(shù)據(jù)變化時(shí),React都會(huì)重新構(gòu)建整個(gè)DOM樹,然后React將當(dāng)前整個(gè)DOM樹和上一次的DOM樹進(jìn)行對(duì)比,得到DOM結(jié)構(gòu)的區(qū)別,然后僅僅將需要變化的部分進(jìn)行實(shí)際的瀏覽器DOM更新。而且React能夠批處理虛擬DOM的刷新,在一個(gè)事件循環(huán)(Event Loop)內(nèi)的兩次數(shù)據(jù)變化會(huì)被合并,例如你連續(xù)的先將節(jié)點(diǎn)內(nèi)容從A-B,B-A,React會(huì)認(rèn)為A變成B,然后又從B變成A UI不發(fā)生任何變化,而如果通過(guò)手動(dòng)控制,這種邏輯通常是極其復(fù)雜的。

盡管每一次都需要構(gòu)造完整的虛擬DOM樹,但是因?yàn)樘摂MDOM是內(nèi)存數(shù)據(jù),性能是極高的,部而對(duì)實(shí)際DOM進(jìn)行操作的僅僅是Diff分,因而能達(dá)到提高性能的目的。這樣,在保證性能的同時(shí),開發(fā)者將不再需要關(guān)注某個(gè)數(shù)據(jù)的變化如何更新到一個(gè)或多個(gè)具體的DOM元素,而只需要關(guān)心在任意一個(gè)數(shù)據(jù)狀態(tài)下,整個(gè)界面是如何Render的。

React Fiber:

在react 16之后發(fā)布的一種react 核心算法,React Fiber是對(duì)核心算法的一次重新實(shí)現(xiàn)(官網(wǎng)說(shuō)法)。之前用的是diff算法。

在之前React中,更新過(guò)程是同步的,這可能會(huì)導(dǎo)致性能問題。

當(dāng)React決定要加載或者更新組件樹時(shí),會(huì)做很多事,比如調(diào)用各個(gè)組件的生命周期函數(shù),計(jì)算和比對(duì)Virtual DOM,最后更新DOM樹,這整個(gè)過(guò)程是同步進(jìn)行的,也就是說(shuō)只要一個(gè)加載或者更新過(guò)程開始,中途不會(huì)中斷。因?yàn)镴avaScript單線程的特點(diǎn),如果組件樹很大的時(shí)候,每個(gè)同步任務(wù)耗時(shí)太長(zhǎng),就會(huì)出現(xiàn)卡頓。

React Fiber的方法其實(shí)很簡(jiǎn)單——分片。把一個(gè)耗時(shí)長(zhǎng)的任務(wù)分成很多小片,每一個(gè)小片的運(yùn)行時(shí)間很短,雖然總時(shí)間依然很長(zhǎng),但是在每個(gè)小片執(zhí)行完之后,都給其他任務(wù)一個(gè)執(zhí)行的機(jī)會(huì),這樣唯一的線程就不會(huì)被獨(dú)占,其他任務(wù)依然有運(yùn)行的機(jī)會(huì)。

React的特點(diǎn)和優(yōu)勢(shì)

1、虛擬DOM

我們以前操作dom的方式是通過(guò)document.getElementById()的方式,這樣的過(guò)程實(shí)際上是先去讀取html的dom結(jié)構(gòu),將結(jié)構(gòu)轉(zhuǎn)換成變量,再進(jìn)行操作

而reactjs定義了一套變量形式的dom模型,一切操作和換算直接在變量中,這樣減少了操作真實(shí)dom,性能真實(shí)相當(dāng)?shù)母撸椭髁鱉VC框架有本質(zhì)的區(qū)別,并不和dom打交道

2、組件系統(tǒng)

react最核心的思想是將頁(yè)面中任何一個(gè)區(qū)域或者元素都可以看做一個(gè)組件 component

那么什么是組件呢?

組件指的就是同時(shí)包含了html、css、js、image元素的聚合體

使用react開發(fā)的核心就是將頁(yè)面拆分成若干個(gè)組件,并且react一個(gè)組件中同時(shí)耦合了css、js、image,這種模式整個(gè)顛覆了過(guò)去的傳統(tǒng)的方式

3、單向數(shù)據(jù)流

其實(shí)reactjs的核心內(nèi)容就是數(shù)據(jù)綁定,所謂數(shù)據(jù)綁定指的是只要將一些服務(wù)端的數(shù)據(jù)和前端頁(yè)面綁定好,開發(fā)者只關(guān)注實(shí)現(xiàn)業(yè)務(wù)就行了

4、JSX 語(yǔ)法

在vue中,我們使用render函數(shù)來(lái)構(gòu)建組件的dom結(jié)構(gòu)性能較高,因?yàn)槭∪チ瞬檎液途幾g模板的過(guò)程,但是在render中利用createElement創(chuàng)建結(jié)構(gòu)的時(shí)候代碼可讀性較低,較為復(fù)雜,此時(shí)可以利用jsx語(yǔ)法來(lái)在render中創(chuàng)建dom,解決這個(gè)問題,但是前提是需要使用工具來(lái)編譯jsx

編寫第一個(gè)react應(yīng)用程序

react開發(fā)需要引入多個(gè)依賴文件:react.js、react-dom.js,分別又有開發(fā)版本和生產(chǎn)版本,create-react-app里已經(jīng)幫我們把這些東西都安裝好了。把通過(guò)CRA創(chuàng)建的工程目錄下的src目錄清空,然后在里面重新創(chuàng)建一個(gè)index.js. 寫入以下代碼:

// 從 react 的包當(dāng)中引入了 React。只要你要寫 React.js 組件就必須引入React, 因?yàn)閞eact里有一種語(yǔ)法叫JSX,稍后會(huì)講到JSX,要寫JSX,就必須引入Reactimport React from 'react'// ReactDOM 可以幫助我們把 React 組件渲染到頁(yè)面上去,沒有其它的作用了。它是從 react-dom 中引入的,而不是從 react 引入。import ReactDOM from 'react-dom'// ReactDOM里有一個(gè)render方法,功能就是把組件渲染并且構(gòu)造 DOM 樹,然后插入到頁(yè)面上某個(gè)特定的元素上ReactDOM.render(// 這里就比較奇怪了,它并不是一個(gè)字符串,看起來(lái)像是純 HTML 代碼寫在 JavaScript 代碼里面。語(yǔ)法錯(cuò)誤嗎?這并不是合法的 JavaScript 代碼, “在 JavaScript 寫的標(biāo)簽的”語(yǔ)法叫 JSX- JavaScript XML。  <h2>歡迎進(jìn)入React的世界</h2>,// 渲染到哪里  document.getElementById('root'))

元素與組件

如果代碼多了之后,不可能一直在render方法里寫,所以就需要把里面的代碼提出來(lái),定義一個(gè)變量,像這樣:

import React from 'react'import ReactDOM from 'react-dom'// 這里感覺又不習(xí)慣了?這是在用JSX定義一下react元素const app = <h2>歡迎進(jìn)入React的世界</h2>ReactDOM.render(

  app,

  document.getElementById('root'))

函數(shù)式組件

由于元素沒有辦法傳遞參數(shù),所以我們就需要把之前定義的變量改為一個(gè)方法,讓這個(gè)方法去return一個(gè)元素:

import React from 'react'import ReactDOM from 'react-dom'// 特別注意這里的寫法,如果要在JSX里寫js表達(dá)式(只能是表達(dá)式,不能流程控制),就需要加 {},包括注釋也是一樣,并且可以多層嵌套const app = (props) => <h2>歡迎進(jìn)入{props.name}的世界</h2>ReactDOM.render(

  app({

    name: 'react'

  }),

  document.getElementById('root'))

這里我們定義的方法實(shí)際上也是react定義組件的第一種方式-定義函數(shù)式組件,這也是無(wú)狀態(tài)組件。但是這種寫法不符合react的jsx的風(fēng)格,更好的方式是使用以下方式進(jìn)行改造

import React from 'react'import ReactDOM from 'react-dom'const App = (props) => <h2>歡迎進(jìn)入{props.name}的世界</h2>ReactDOM.render(

  // React組件的調(diào)用方式  <App name="react" />,

  document.getElementById('root'))

這樣一個(gè)完整的函數(shù)式組件就定義好了。但要注意!注意!注意!組件名必須大寫,否則報(bào)錯(cuò)。

class組件

ES6的加入讓JavaScript直接支持使用class來(lái)定義一個(gè)類,react的第二種創(chuàng)建組件的方式就是使用的類的繼承,ES6 class是目前官方推薦的使用方式,它使用了ES6標(biāo)準(zhǔn)語(yǔ)法來(lái)構(gòu)建,看以下代碼:

import React from 'react'import ReactDOM from 'react-dom'class App extends React.Component {

  render () {

    return (

      // 注意這里得用this.props.name, 必須用this.props      <h2>歡迎進(jìn)入{this.props.name}的世界</h2>

    )

  }}ReactDOM.render(

  <App name="react" />,

  document.getElementById('root'))

運(yùn)行結(jié)果和之前完全一樣,因?yàn)镴S里沒有真正的class,這個(gè)class只是一個(gè)語(yǔ)法糖, 但二者的運(yùn)行機(jī)制底層運(yùn)行機(jī)制不一樣。

· 函數(shù)式組件是直接調(diào)用, 在前面的代碼里已經(jīng)有看到

· es6 class組件其實(shí)就是一個(gè)構(gòu)造器,每次使用組件都相當(dāng)于在實(shí)例化組件,像這樣:

import React from 'react'import ReactDOM from 'react-dom'class App extends React.Component {

 render () {

 return (

   <h2>歡迎進(jìn)入{this.props.name}的世界</h2>

  )

  }}const app = new App({

 name: 'react'}).render()ReactDOM.render(

 app,

 document.getElementById('root'))

更老的一種方法

在16以前的版本還支持這樣創(chuàng)建組件, 但現(xiàn)在的項(xiàng)目基本上不用

React.createClass({

  render () {

    return (

      <div>{this.props.xxx}</div>

    )

  }})

組件的組合、嵌套

將一個(gè)組件渲染到某一個(gè)節(jié)點(diǎn)里的時(shí)候,會(huì)將這個(gè)節(jié)點(diǎn)里原有內(nèi)容覆蓋

組件嵌套的方式就是將子組件寫入到父組件的模板中去,且react沒有Vue中的內(nèi)容分發(fā)機(jī)制(slot),所以我們?cè)谝粋€(gè)組件的模板中只能看到父子關(guān)系

// 從 react 的包當(dāng)中引入了 React 和 React.js 的組件父類 Component// 還引入了一個(gè)React.js里的一種特殊的組件 Fragmentimport React, { Component, Fragment } from 'react'import ReactDOM from 'react-dom'class Title extends Component {

  render () {

    return (

      <h2>歡迎進(jìn)入React的世界</h2>

    )

  }}class Content extends Component {

  render () {

    return (

      <p>React.js是一個(gè)構(gòu)建UI的庫(kù)</p>

    )

  }}/** 由于每個(gè)React組件只能有一個(gè)根節(jié)點(diǎn),所以要渲染多個(gè)組件的時(shí)候,需要在最外層包一個(gè)容器,如果使用div, 會(huì)生成多余的一層domclass App extends Component {  render () {    return (        <div>            <Title />        <Content />      </div>    )  }}**/// 如果不想生成多余的一層dom可以使用React提供的Fragment組件在最外層進(jìn)行包裹class App extends Component {

  render () {

    return (

      <Fragment>

        <Title />

        <Content />

      </Fragment>

    )

  }}ReactDOM.render(

  <App/>,

  document.getElementById('root'))

#JSX 原理

要明白JSX的原理,需要先明白如何用 JavaScript 對(duì)象來(lái)表現(xiàn)一個(gè) DOM 元素的結(jié)構(gòu)?

看下面的DOM結(jié)構(gòu)

<div class='app' id='appRoot'>

  <h2 class='title'>歡迎進(jìn)入React的世界</h2>

  <p>

    React.js 是一個(gè)幫助你構(gòu)建頁(yè)面 UI 的庫(kù)

  </p></div>

上面這個(gè) HTML 所有的信息我們都可以用 JavaScript 對(duì)象來(lái)表示:

{

  tag: 'div',

  attrs: { className: 'app', id: 'appRoot'},

  children: [

    {

      tag: 'h2',

      attrs: { className: 'title' },

      children: ['歡迎進(jìn)入React的世界']

    },

    {

      tag: 'p',

      attrs: null,

      children: ['React.js 是一個(gè)構(gòu)建頁(yè)面 UI 的庫(kù)']

    }

  ]}

但是用 JavaScript 寫起來(lái)太長(zhǎng)了,結(jié)構(gòu)看起來(lái)又不清晰,用 HTML 的方式寫起來(lái)就方便很多了。

于是 React.js 就把 JavaScript 的語(yǔ)法擴(kuò)展了一下,讓 JavaScript 語(yǔ)言能夠支持這種直接在 JavaScript 代碼里面編寫類似 HTML 標(biāo)簽結(jié)構(gòu)的語(yǔ)法,這樣寫起來(lái)就方便很多了。編譯的過(guò)程會(huì)把類似 HTML 的 JSX 結(jié)構(gòu)轉(zhuǎn)換成 JavaScript 的對(duì)象結(jié)構(gòu)。

下面代碼:

import React from 'react'import ReactDOM from 'react-dom'class App extends React.Component {

  render () {

    return (

      <div className='app' id='appRoot'>

        <h2 className='title'>歡迎進(jìn)入React的世界</h2>

        <p>

          React.js 是一個(gè)構(gòu)建頁(yè)面 UI 的庫(kù)

        </p>

      </div>

    )

  }}ReactDOM.render(

    <App />,

  document.getElementById('root'))

編譯之后將得到這樣的代碼:

import React from 'react'import ReactDOM from 'react-dom'class App extends React.Component {

  render () {

    return (

      React.createElement(

        "div",

        {

          className: 'app',

          id: 'appRoot'

        },

        React.createElement(

          "h2",

          { className: 'title' },

          "歡迎進(jìn)入React的世界"

        ),

        React.createElement(

          "p",

          null,

          "React.js 是一個(gè)構(gòu)建頁(yè)面 UI 的庫(kù)"

        )

      )

    )

  }}ReactDOM.render(

    React.createElement(App),

  document.getElementById('root'))

React.createElement 會(huì)構(gòu)建一個(gè) JavaScript 對(duì)象來(lái)描述你 HTML 結(jié)構(gòu)的信息,包括標(biāo)簽名、屬性、還有子元素等, 語(yǔ)法為

React.createElement(

  type,

  [props],

  [...children])

所謂的 JSX 其實(shí)就是 JavaScript 對(duì)象,所以使用 React 和 JSX 的時(shí)候一定要經(jīng)過(guò)編譯的過(guò)程:

JSX —使用react構(gòu)造組件,bable進(jìn)行編譯—> JavaScript對(duì)象 — ReactDOM.render()—>DOM元素 —>插入頁(yè)面

組件中DOM樣式

· 行內(nèi)樣式

想給虛擬dom添加行內(nèi)樣式,需要使用表達(dá)式傳入樣式對(duì)象的方式來(lái)實(shí)現(xiàn):

// 注意這里的兩個(gè)括號(hào),第一個(gè)表示我們?cè)谝狫SX里插入JS了,第二個(gè)是對(duì)象的括號(hào) <p style={{color:'red', fontSize:'14px'}}>Hello world</p>

行內(nèi)樣式需要寫入一個(gè)樣式對(duì)象,而這個(gè)樣式對(duì)象的位置可以放在很多地方,例如render函數(shù)里、組件原型上、外鏈js文件中

· 使用class

React推薦我們使用行內(nèi)樣式,因?yàn)镽eact覺得每一個(gè)組件都是一個(gè)獨(dú)立的整體

其實(shí)我們大多數(shù)情況下還是大量的在為元素添加類名,但是需要注意的是,class需要寫成className(因?yàn)楫吘故窃趯戭恓s代碼,會(huì)收到j(luò)s規(guī)則的現(xiàn)在,而class是關(guān)鍵字)

<p className="hello" style = {this.style}>Hello world</p>

· 不同的條件添加不同的樣式

有時(shí)候需要根據(jù)不同的條件添加不同的樣式,比如:完成狀態(tài),完成是綠色,未完成是紅色。那么這種情況下,我們推薦使用classnames這個(gè)包:

· css-in-js

styled-components是針對(duì)React寫的一套css-in-js框架,簡(jiǎn)單來(lái)講就是在js中寫css。npm鏈接

TodoList

組件化開發(fā)React todolist, 項(xiàng)目開發(fā)中的組件的基本目錄結(jié)構(gòu)基本上是這樣的:

React的相關(guān)知識(shí)點(diǎn)有哪些

注意:一個(gè)組件只干一件事情 ,所以TodoList和TodoItem要做成兩個(gè)組件,這樣也方便于后期理解shouldComponentUpdate

關(guān)于“React的相關(guān)知識(shí)點(diǎn)有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI