日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

react render没更新_web前端教程分享React学习笔记(一)

發(fā)布時間:2025/4/5 HTML 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 react render没更新_web前端教程分享React学习笔记(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  web前端教程分享React學(xué)習(xí)筆記(一),React的起源和發(fā)展:React 起源于 Facebook 的內(nèi)部項目,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設(shè)Instagram 的網(wǎng)站。做出來以后,發(fā)現(xiàn)這套東西很好用,就在2013年5月開源了。

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

輕量級的視圖層庫!A JavaScript library for building user interfaces

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

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

React高性能的原理:

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

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

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

React Fiber:

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

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

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

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

React的特點和優(yōu)勢

1、虛擬DOM

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

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

2、組件系統(tǒng)

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

那么什么是組件呢?

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

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

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

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

4、JSX 語法

在vue中,我們使用render函數(shù)來構(gòu)建組件的dom結(jié)構(gòu)性能較高,因為省去了查找和編譯模板的過程,但是在render中利用createElement創(chuàng)建結(jié)構(gòu)的時候代碼可讀性較低,較為復(fù)雜,此時可以利用jsx語法來在render中創(chuàng)建dom,解決這個問題,但是前提是需要使用工具來編譯jsx

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

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

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

元素與組件

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

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

app,

document.getElementById('root'))

函數(shù)式組件

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

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

app({

name: 'react'

}),

document.getElementById('root'))

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

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

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

document.getElementById('root'))

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

class組件

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

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

render () {

return (

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

)

}}ReactDOM.render(

<App name="react" />,

document.getElementById('root'))

運行結(jié)果和之前完全一樣,因為JS里沒有真正的class,這個class只是一個語法糖, 但二者的運行機(jī)制底層運行機(jī)制不一樣。

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

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

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

render () {

return (

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

)

}}?const app = new App({

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

app,

document.getElementById('root'))

更老的一種方法

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

React.createClass({

render () {

return (

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

)

}})

組件的組合、嵌套

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

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

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

render () {

return (

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

)

}}class Content extends Component {

render () {

return (

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

)

}}/** 由于每個React組件只能有一個根節(jié)點,所以要渲染多個組件的時候,需要在最外層包一個容器,如果使用div, 會生成多余的一層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 對象來表現(xiàn)一個 DOM 元素的結(jié)構(gòu)?

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

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

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

<p>

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

</p></div>

上面這個 HTML 所有的信息我們都可以用 JavaScript 對象來表示:

{

tag: 'div',

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

children: [

{

tag: 'h1',

attrs: { className: 'title' },

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

},

{

tag: 'p',

attrs: null,

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

}

]}

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

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

下面代碼:

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

render () {

return (

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

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

<p>

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

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

"h1",

{ className: 'title' },

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

),

React.createElement(

"p",

null,

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

)

)

)

}}?ReactDOM.render(

React.createElement(App),

document.getElementById('root'))

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

React.createElement(

type,

[props],

[...children])

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

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

組件中DOM樣式

· 行內(nèi)樣式

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

// 注意這里的兩個括號,第一個表示我們在要JSX里插入JS了,第二個是對象的括號 <p style={{color:'red', fontSize:'14px'}}>Hello world</p>

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

· 使用class

React推薦我們使用行內(nèi)樣式,因為React覺得每一個組件都是一個獨立的整體

其實我們大多數(shù)情況下還是大量的在為元素添加類名,但是需要注意的是,class需要寫成className(因為畢竟是在寫類js代碼,會收到j(luò)s規(guī)則的現(xiàn)在,而class是關(guān)鍵字)

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

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

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

· css-in-js

styled-components是針對React寫的一套css-in-js框架,簡單來講就是在js中寫css。npm鏈接

TodoList

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

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

總結(jié)

以上是生活随笔為你收集整理的react render没更新_web前端教程分享React学习笔记(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。