日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

react自看

發(fā)布時(shí)間:2023/12/8 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 react自看 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 1 為什么要使用React
  • 2 React的定義
  • 3 React的三大特性
  • 4 React入門
    • 4.1 hello_react
    • 4.2 虛擬DOM的創(chuàng)建
    • 4.3 JSX
    • 4.4 模塊與組件,模塊化與組件化的理解
  • 5 React面向組件編程
    • 5.1 基本理解和使用
    • 5.2 組件實(shí)例的三大核心屬性
      • 5.2.1 state
      • 5.2.2 props
      • 5.2.3 ref
    • 5.3 React中的事件處理
    • 5.4 React中收集表單數(shù)據(jù)
      • 5.4.1 非受控組件與非受控組件
    • 5.5 組件的 生命周期
      • 5.5.1 效果
      • 5.5.2. 掛載與卸載
      • 5.5.3 理解
      • 5.5.4 生命周期流程圖(舊)
      • 5.5.5 生命周期流程圖(新)
      • 5.5.6 重要勾子和即將廢棄的勾子
    • 5.6 虛擬DOM與DOM Diffing算法
  • 6 React應(yīng)用(基于React腳手架)
    • 6.1 使用create-react-app創(chuàng)建react應(yīng)用
      • 6.1.1 react腳手架
      • 6.1.2 創(chuàng)建項(xiàng)目并啟動(dòng)
      • 6.1.3 react腳手架項(xiàng)目結(jié)構(gòu)
      • 6.1.4 功能界面的組件化編碼流程(通用)
    • 6.2 react ajax
      • 6.2.1 理解
      • 6.2.2 axios
      • 6.2.3 react腳手架配置代理總結(jié)
      • 6.2.4 消息訂閱-發(fā)布機(jī)制
      • 6.2.5 擴(kuò)展:Fetch(關(guān)注分離思想)
  • 7 React路由
    • 7.1 相關(guān)理解
      • 7.1.1 SPA 的理解
      • 7.1.2 路由的理解
      • 7.1 .3 react-router-dom的理解
    • 7.2 react-router-dom相關(guān)API
      • 7.2.1 內(nèi)置組件
      • 7.2.2. 其它
  • 8 代碼
  • 9 參考

1 為什么要使用React

  • 開發(fā)迅速。React組件化的特性使得React可以在項(xiàng)目中大量復(fù)用封裝好的組件,提高代碼的復(fù)用率,減少了重復(fù)寫相同代碼的繁瑣而無聊的工作
    • 原生的JavaScript操作DOM繁瑣,效率低(DOM-API操作UI)
    • 使用JavaScript,包括jQuery直接操作DOM,瀏覽器會進(jìn)行大量的重繪和重排(雖然jQuery簡化了操作DOM的步驟,但依然效率低下)
    • 原生的JavaScript沒有組件化編碼方案,代碼復(fù)用率低
  • 生態(tài)相對完善。React 起源于 Facebook 的內(nèi)部項(xiàng)目,具有相對穩(wěn)定的維護(hù),周邊生態(tài)相對完善,像各種的UI庫,路由庫等,可以在更少的時(shí)間內(nèi)完成更多的工作。
  • 有大公司作為背書。除了React的開發(fā)公司Faceboook大量使用React外,國內(nèi)外還有很多大公司也廣泛應(yīng)用React,在國外有Paypal,Airbnb等,在國內(nèi)有阿里,騰訊,字節(jié)跳動(dòng)等。
  • 有強(qiáng)大的開源社區(qū)。開源項(xiàng)目的社區(qū)非常重要,在社區(qū)開發(fā)者的貢獻(xiàn)下會讓一些開源項(xiàng)目變得越來越好,項(xiàng)目的issue的解決速度也會得到提升,同時(shí)還會提供大量的周邊技術(shù)工具和技術(shù)博客。
  • 2 React的定義

    React的定義:用于構(gòu)建用戶界面的JavaScript庫。
    關(guān)鍵字

  • 構(gòu)建用戶界面:說明React專注于視圖的構(gòu)建,既不是一個(gè)請求庫,也不是一個(gè)打包工具,而是主要提供UI層面的解決方案。
  • JavaScript庫:這說明React并不是一個(gè)框架,并不能解決項(xiàng)目中的所有問題,為了在項(xiàng)目中使用它,需要結(jié)合其他的庫,例如Redux/React-router等來協(xié)助提供完整的解決方案。在這些周邊生態(tài)的配合下才能組合成一個(gè)框架
  • 換句話來說,React所做的有三步

  • 發(fā)送請求獲得數(shù)據(jù)
  • 處理數(shù)據(jù)(過濾,整理格式等)
  • 操作DOM呈現(xiàn)頁面
  • 也就是說React也可以定義為一個(gè)將數(shù)據(jù)渲染為HTML視圖的開源JavaScript庫。

    3 React的三大特性

  • 聲明式編程
  • 命令式編程 VS 聲明式編程:

    簡單來說,命令式編程就是通過代碼來告訴計(jì)算機(jī)去做什么。

    而聲明式編程是通過代碼來告訴計(jì)算機(jī)你想要做什么,讓計(jì)算機(jī)想出如何去做。

    舉個(gè)生活中的例子就是:
    命令式編程:我想喝一個(gè)冰可樂,然后我就會對身邊的XXX說:“XXX,你去廚房,打開冰箱,拿出一瓶冰可樂,打開之后送過來給我。”
    聲明式編程:我想喝一個(gè)冰可樂,然后我就會對身邊的XXX說:“XXX,我想喝冰可樂。”而具體他是怎么拿到的冰可樂,怎么送過來的,是下樓買的還是在冰箱里拿的,我并不關(guān)心,我只關(guān)心我喝冰可樂的需求是否得到了滿足。

    用代碼來舉個(gè)例子:
    如果我要在界面上展示一個(gè)按鈕,并且點(diǎn)擊按鈕后會改變該按鈕的class。

    用DOM編程寫的代碼就是命令式編程:首先你要指揮瀏覽器,第一步先要找到id為container的節(jié)點(diǎn),然后創(chuàng)建一個(gè)button element,接著給這個(gè)button添加一個(gè)class name,然后添加一個(gè)點(diǎn)擊事件,最后將button添加到container節(jié)點(diǎn)里。這整個(gè)過程每一步操作都是命令式的,一步一步告訴瀏覽器要做什么。

    const container = document. getElementById ( "container" ); const btn = document.createElement ("button");

    btn.className = "btn red " ;
    btn.textContent = “Demo” ;

    btn.onclick = function ( ) {
    if ( this.classList.contains ( “red” ) ) {
    this.classList.remove( “red” );
    this.classList.add ( “blue” );
    }else {
    this.classList.remove( “blue” );
    this.classList.add ( “red” );
    }
    };
    container.appendChild( btn);

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    而要實(shí)現(xiàn)相同功能,采用聲明式編程的React就簡單得多了。
    首先我們定義一個(gè)Button組件,在render函數(shù)里通過返回一個(gè)類似HTML的數(shù)據(jù)結(jié)構(gòu),告訴React我要渲染一個(gè)Button,它是id為container的子節(jié)點(diǎn)。Button上的ClassName是動(dòng)態(tài)變化的,當(dāng)點(diǎn)擊按鈕時(shí)class要改變,這樣就可以了。至于render什么時(shí)候被執(zhí)行,是如何渲染到頁面上的,點(diǎn)擊按鈕之后classname是如何更新的,這些都不需要你關(guān)心,你只需要告訴React你希望當(dāng)前的UI應(yīng)該是一個(gè)什么樣的狀態(tài)就可以了。

    class Button extends React. Component {state = { color: "red" };handleChange =()=> {const color = this.state.color == "red" ? "blue" : "red" ;this.setState({ color });};render( ) {return (<div id="container"><buttonclassName={ `btn ${this.state.color}` }onclick={this.handleChange}>Demo</button></div>);} }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 組件化:React提供了一種全新的語法擴(kuò)展,JSX。JSX創(chuàng)造性地將渲染邏輯和UI邏輯結(jié)合在了一起,而這個(gè)結(jié)合體在React中就被稱為組件。一個(gè)頁面由多個(gè)組件組成,甚至整個(gè)應(yīng)用都可以視為一個(gè)組件,只不過是最大的組件。組件可以層層嵌套,一個(gè)組件可以由多個(gè)組件組成,一個(gè)大的組件由很多個(gè)小組件組成,這些小組件也有可能由更小的組件組成。同一個(gè)組件可能會被使用在不同的地方。

    組件化的出現(xiàn)大幅度地提升了代碼地復(fù)用率,同時(shí)也改變了前端開發(fā)人員的一個(gè)編程思維
  • 一次學(xué)會,隨處編寫:這句話的意思不是學(xué)會了想寫什么就可以寫什么,也不是說寫一次想在哪里跑就在哪里跑,而是說學(xué)會后可以在很多地方使用React的語法來寫代碼,比如配合React DOM來編寫web端的頁面,配合React Native來寫手機(jī)客戶端APP,配合React 360開發(fā)VR界面等。

    React的靈活性是由于它自身的定位決定的。React是一個(gè)用于構(gòu)建用戶界面的JS庫,對于React來說,這里的用戶界面是一個(gè)抽象的虛擬的用戶界面,其實(shí)就是一個(gè)描述頁面狀態(tài)的數(shù)據(jù)結(jié)構(gòu)。web頁面,移動(dòng)客戶端頁面,VR界面都是用戶界面,只要配合相應(yīng)的渲染器就能在不同的平臺中展示正確的UI界面。

    通俗來說,我們可以把React的執(zhí)行結(jié)果想象成一個(gè)視頻文件數(shù)據(jù),在不同的播放器設(shè)備,我們通過轉(zhuǎn)換器將視頻編譯成不同的格式來讓他們在不同的播放器上正常地播放。所以在寫web端React時(shí)我們要額外引入React DOM來做渲染。
  • 此外,React使用虛擬DOM+優(yōu)秀的Diffing算法,盡量減少與真實(shí)DOM的交互,最小化頁面重繪

    4 React入門

    4.1 hello_react

    4.2 虛擬DOM的創(chuàng)建

  • 創(chuàng)建虛擬DOM的兩種方式

    • 純JS方式(一般不用,過于繁瑣)
    • JSX方式(簡單方便,最終由babel翻譯成js的形式,與用js寫的結(jié)果一樣)
  • 虛擬DOM和真實(shí)DOM

    • React提供一些API來創(chuàng)建一種“特別”的一般js對象

      const VDOM = React.createElement('xx',{id:'xx'},'xx')///依次為標(biāo)簽名,標(biāo)簽屬性和標(biāo)簽內(nèi)容
      • 1

      上面創(chuàng)建的就是一個(gè)簡單的虛擬DOM對象

      [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-nCawKD9t-1624953908993)(https://i.loli.net/2021/04/25/qwd6egtIJMapLmA.png)]

    • 我們編碼時(shí)基本只需要操作react的虛擬DOM相關(guān)數(shù)據(jù),react就會轉(zhuǎn)換為真實(shí)的DOM

    關(guān)于虛擬DOM總結(jié):

  • 本質(zhì)是Object類型的對象(一般對象)
  • 虛擬DOM比較“輕”,真實(shí)DOM比較“重”,因?yàn)樘摂MDOM是React內(nèi)部在用,無需真實(shí)DOM上那么多的屬性
  • 虛擬DOM對象最終都會被React轉(zhuǎn)換為真實(shí)DOM,呈現(xiàn)在頁面上
  • 4.3 JSX

    鏈接:JSX基本語法規(guī)則

  • 全稱: JavaScript XML

  • react定義的一種類似于XML的JS擴(kuò)展語法: JS + XML,本質(zhì)上還是JavaScript

  • 是**React.createElement(component, props, …children)**方法的語法糖

  • 作用:用來簡化創(chuàng)建虛擬DOM

    • 寫法:var ele =

      Hello JSX!

    • 它不是字符串(不要加引號),也不是HTML/XML標(biāo)簽
    • 它最終產(chǎn)生的就是一個(gè)js對象
  • 標(biāo)簽名任意:HTML標(biāo)簽或其他標(biāo)簽

  • 標(biāo)簽屬性隨意:HTML標(biāo)簽屬性或其它

  • 基本語法規(guī)則

    • 標(biāo)簽首字母

      ? (1)若小寫字母開頭,則將該標(biāo)簽轉(zhuǎn)為HTML中同名元素,若HTML中無該標(biāo)簽對應(yīng)的同名元素,則報(bào)錯(cuò)。

      ? (2)若大寫字母開頭,則react就去渲染對用的組件,若組件沒有定義,則報(bào)錯(cuò)

    • 標(biāo)簽中的js表達(dá)式必須用{ }包含

      一定要區(qū)分:【JS語句(代碼)】與【js表達(dá)式】

    • 表達(dá)式:一個(gè)表達(dá)式會產(chǎn)生一個(gè)值,可以放在任何一個(gè)需要值的地方

      下面這些都是表達(dá)式:

      • a
      • a+b
      • demo(1) //函數(shù)調(diào)用表達(dá)式
      • arr.map()
      • function test() { }
    • 語句(代碼):不產(chǎn)生值

      ? 下面這些都是語句(代碼):

      • if(){}
      • for(){}
      • switch(){case:xxx}
    • 注釋需要寫在花括號{}中

    • 樣式的類名指定不要寫class,要寫className

    • 內(nèi)聯(lián)樣式要用style={undefined{key:value}}的形式寫第一個(gè){}表示里面是一個(gè)js表達(dá)式,第二個(gè){}表示里面是一個(gè)鍵值對,里面要寫小駝峰的形式, 比如font-size要寫成fontSize

      <span style={undefined{color:’#e0e0e0’, fontSize:18} }> myData

    • 虛擬DOM只能有一個(gè)根標(biāo)簽,有多個(gè)標(biāo)簽時(shí),可用一個(gè)div包起來

    • 標(biāo)簽必須閉合

  • babel.js的作用
    • 瀏覽器不能直接解析JSX代碼, 需要babel轉(zhuǎn)譯為純JS的代碼才能運(yùn)行
    • 只要用了JSX,都要加上type=“text/babel”, 聲明需要babel來處理

    4.4 模塊與組件,模塊化與組件化的理解

  • 模塊
    • 理解:向外提供特定功能的js程序,一般就是一個(gè)js文件
    • 為什么要拆成模塊:因?yàn)殡S著業(yè)務(wù)邏輯增加,代碼越來越多且復(fù)雜
    • 作用:服用js,簡化js的編寫,提高js運(yùn)行效率
  • 組件
    • 理解:用來實(shí)現(xiàn)局部功能的代碼和資源的集合(html/css/js/image等等)
    • 為什么一個(gè)界面的功能很復(fù)雜,不可能寫成一整塊,要分成一塊塊寫,然后拼起來
    • 作用:復(fù)用編碼,簡化項(xiàng)目編碼,提高運(yùn)行效率
  • 模塊化
  • 當(dāng)一個(gè)應(yīng)用的js都是以模塊來編寫,這個(gè)應(yīng)用就是一個(gè)模塊化的應(yīng)用

  • 組件化
  • 當(dāng)應(yīng)用是以多組件的方式實(shí)現(xiàn),這個(gè)應(yīng)用就是一個(gè)組件化的應(yīng)用

    5 React面向組件編程

    5.1 基本理解和使用

    組件的類型

  • 函數(shù)式組件:用函數(shù)定義的組件,適用于簡單組件的定義(沒有實(shí)例,this=undefined)
  • ? 注意:

    ? (1)組件名必須首字母大寫

    ? (2)虛擬DOM元素只能有一個(gè)根元素

    ? (3)虛擬DOM元素必須有結(jié)束標(biāo)簽

  • 類式組件:用類定義的組件,適用于復(fù)雜組件的定義(有實(shí)例)
  • 簡單組件:無狀態(tài)的組件

    復(fù)雜組件:有狀態(tài)(state)的組件

    狀態(tài):舉例子說

    • 人是有狀態(tài)的,比如今天的精神如何,人的狀態(tài)會影響人的行為
    • 組件也是有狀態(tài)的,組件的狀態(tài)驅(qū)動(dòng)頁面,數(shù)據(jù)放在狀態(tài)里

    5.2 組件實(shí)例的三大核心屬性

    5.2.1 state

  • 理解:
    • state是組件對象最重要的屬性, 值是==對象(==可以包含多個(gè)key-value的組合),用{}包裹
    • 組件被稱為"狀態(tài)機(jī)", 通過更新組件的state來更新對應(yīng)的頁面顯示(重新渲染組件)
  • 注意:
    • 組件中render方法中的this為組件實(shí)例對象
    • 組件自定義的方法中this為undefined(作為事件的回調(diào)使用),如何解決?
      • a) 強(qiáng)制綁定this: 通過函數(shù)對象的bind()
      • b) 箭頭函數(shù)【要寫成賦值語句+箭頭函數(shù)的形式,類里面不支持function(){ }這種形式】
    • 狀態(tài)數(shù)據(jù),不能直接修改或更新,要用setState

    5.2.2 props

  • 理解:
    • 每個(gè)組件對象都會有props(properties的簡寫)屬性
    • 組件標(biāo)簽的所有屬性都保存在props中
  • 作用
    • 通過標(biāo)簽屬性從組件外向組件內(nèi)傳遞變化的數(shù)據(jù)
    • 注意: 組件內(nèi)部不要修改props數(shù)據(jù)
  • 編碼操作
    • 內(nèi)部讀取某個(gè)屬性值: this.props.name

    • 對props中的屬性值進(jìn)行類型限制和必要性限制

    • 第一種方式(React v15.5 開始已棄用):

      Person.propTypes = {name: React.PropTypes.string.isRequired,age: React.PropTypes.number }
      • 1
      • 2
      • 3
      • 4
    • 第二種方式(新):使用prop-types庫進(jìn)限制(需要引入prop-types庫)

      Person.propTypes = {name: PropTypes.string.isRequired,age: PropTypes.number. }
      • 1
      • 2
      • 3
      • 4
    • 擴(kuò)展屬性:將對象的所有屬性通過props傳遞:<Person {…person}/>

    • 默認(rèn)屬性值:

    Person.defaultProps = {age: 18,sex:'男' }
    • 1
    • 2
    • 3
    • 4
    • 組件類的構(gòu)造函數(shù)

      constructor(props){super(props)console.log(props)//打印所有屬性 }
      • 1
      • 2
      • 3
      • 4

    5.2.3 ref

  • 理解:組件內(nèi)的標(biāo)簽可以定義ref屬性來標(biāo)識自己

  • 編碼

    • 字符串形式的ref:(已經(jīng)不被react推薦使用)官方說明

      <input ref = 'input1'/>
      • 1
    • 回調(diào)形式的ref

      <input ref={(c)=>{this.input1 = c}}
      • 1
    • createRef創(chuàng)建ref容器

    myRef = React.createRef() ; <input ref={this.myRef}/>
    • 1
    • 2

    5.3 React中的事件處理

  • 通過onXxx屬性指定處理函數(shù)(注意大小寫,與原生的js區(qū)分開)

    ? a) React使用的是自定義(合成)事件, 而不是使用的原生DOM事件 ——目的是為了更好的兼容性

    ? b) React中的事件是通過事件委托方式處理的(委托給組件最外層的元素) ——目的是為了高效

  • 通過event.target得到發(fā)生事件的DOM元素對象 ——為了避免過度使用ref

  • 不要過度使用ref,當(dāng)發(fā)生事件的DOM正好是要操作的DOM元素時(shí)可以用event.target的形式

    5.4 React中收集表單數(shù)據(jù)

    5.4.1 非受控組件與非受控組件

    非受控組件:現(xiàn)用現(xiàn)取(ref)

    受控組件:隨著輸入維護(hù)狀態(tài)為受控組件(onChange , setState)

    5.5 組件的 生命周期

    5.5.1 效果

    需求:定義組件實(shí)現(xiàn)以下功能:

  • 讓指定的文本做顯示 / 隱藏的漸變動(dòng)畫
  • 從完全可見,到徹底消失,耗時(shí)2S
  • 點(diǎn)擊“不活了”按鈕從界面中卸載組件
  • 5.5.2. 掛載與卸載

    掛載:mount。當(dāng) 組件第一次被渲染到 DOM 中的時(shí)候,就為其設(shè)置一個(gè)計(jì)時(shí)器。這在 React 中被稱為“掛載(mount)”。

    卸載:unmount。同時(shí),當(dāng) DOM 中 組件被刪除的時(shí)候,應(yīng)該清除計(jì)時(shí)器。這在 React 中被稱為“卸載(unmount)”

    5.5.3 理解

  • 組件從創(chuàng)建到死亡它會經(jīng)歷一些特定的階段。
  • React組件中包含一系列勾子函數(shù)(生命周期回調(diào)函數(shù)), 會在特定的時(shí)刻調(diào)用。
  • 我們在定義組件時(shí),會在特定的生命周期回調(diào)函數(shù)中,做特定的工作。
  • 5.5.4 生命周期流程圖(舊)

    生命周期的三個(gè)階段(舊)

  • 初始化階段: 由ReactDOM.render()觸發(fā)—初次渲染

    ? 1). constructor()

    ? 2). componentWillMount()

    ? 3). render()

    ? 4). componentDidMount() = = = =>常用,一般在這個(gè)鉤子中做一些初始化的事,例如開啟定時(shí)器、 發(fā)送網(wǎng)絡(luò)請求、訂閱消息、開啟監(jiān)聽, 發(fā)送ajax請求等

  • 更新階段: 由組件內(nèi)部this.setSate()或父組件重新render觸發(fā)

    ? 1). shouldComponentUpdate()

    ? 2). componentWillUpdate()

    ? 3). render() = = = =>必須要使用

    ? 4). componentDidUpdate()

  • 卸載組件: 由ReactDOM.unmountComponentAtNode()觸發(fā)

    ? 1). componentWillUnmount() = = = =>常用,一般在這個(gè)鉤子做一些收尾的工作,例如,關(guān)閉定時(shí) 器、取消訂閱消息

  • 5.5.5 生命周期流程圖(新)

    生命周期的三個(gè)階段(新)

    **1. ** 初始化階段: 由ReactDOM.render()觸發(fā)—初次渲染

    ? constructor()

    getDerivedStateFromProps(新增,很少用,上官網(wǎng)了解即可)

    ? (此方法適用于罕見的用例,即 state 的值在任何時(shí)候都取決于 props)

    ? render()

    ? componentDidMount()

  • 更新階段: 由組件內(nèi)部this.setSate()或父組件重新render觸發(fā)

    ? getDerivedStateFromProps

    ? shouldComponentUpdate()

    render()
    • 1

    **getSnapshotBeforeUpdate ** 在更新之前獲取快照,有點(diǎn)實(shí)用意義

    componentDidUpdate()
    • 1

    **3. ** 卸載組件: 由ReactDOM.unmountComponentAtNode()觸發(fā)

  • ? componentWillUnmount()

    5.5.6 重要勾子和即將廢棄的勾子

  • 重要勾子
    • render:必須要使用,初始化渲染或更新渲染調(diào)用
    • componentDidMount:一般在這個(gè)鉤子中做一些初始化的事,例如開啟定時(shí)器、 發(fā)送網(wǎng)絡(luò)請求、訂閱消息,開啟監(jiān)聽, 發(fā)送ajax請求等
    • componentWillUnmount:做一些收尾工作, 如: 清理定時(shí)器,取消訂閱等
  • 即將廢棄的勾子
    • componentWillMount
    • componentWillReceiveProps
    • componentWillUpdate
  • 16版本能正常使用,17版本使用會出現(xiàn)警告,下一個(gè)大版本需要加上UNSAFE_前綴才能使用,以后可能會被徹底廢棄,不建議使用。

    5.6 虛擬DOM與DOM Diffing算法

  • 基本原理圖
  • 經(jīng)典面試題:

    1). react/vue中的key有什么作用?(key的內(nèi)部原理是什么?)

    2). 為什么遍歷列表時(shí),key最好不要用index?

  • 虛擬DOM中key的作用:

    1). 簡單地說: key是虛擬DOM對象的標(biāo)識, 在更新顯示時(shí)key起著極其重要的作用。

    2). 詳細(xì)地·說: 當(dāng)狀態(tài)中的數(shù)據(jù)發(fā)生變化時(shí),react會根據(jù)【新數(shù)據(jù)】生成【新的虛擬DOM】, 隨后React進(jìn)行【新虛擬DOM】與【舊虛擬DOM】的diff比較,比較規(guī)則如下:

  • ? a. 舊虛擬DOM中找到了與新虛擬DOM相同的key:

    ? (1).若虛擬DOM中內(nèi)容沒變, 直接使用之前的真實(shí)DOM

    ? (2).若虛擬DOM中內(nèi)容變了, 則生成新的真實(shí)DOM,隨后替換掉頁面中之前的真實(shí)DOM

    ? b. 舊虛擬DOM中未找到與新虛擬DOM相同的key

    ? 根據(jù)數(shù)據(jù)創(chuàng)建新的真實(shí)DOM,隨后渲染到到頁面

  • 用index作為key可能會引發(fā)的問題:
  • ? 1) 若對數(shù)據(jù)進(jìn)行:逆序添加、逆序刪除等破壞順序操作:

    ? 會產(chǎn)生沒有必要的真實(shí)DOM更新 ==> 界面效果沒問題, 但效率低。

    ? 2.)如果結(jié)構(gòu)中還包含輸入類的DOM:

    ? 會產(chǎn)生錯(cuò)誤DOM更新 ==> 界面有問題。

    ? 3) ==注意!==如果不存在對數(shù)據(jù)的逆序添加、逆序刪除等破壞順序操作, 僅用于渲染列表用于展 示,使用index作為key是沒有問題的。

    ?

    ? 3. 開發(fā)中如何選擇key?:

    ? 1) 最好使用每條數(shù)據(jù)的唯一標(biāo)識作為key, 比如id、手機(jī)號、身份證號、學(xué)號等唯一值。

    ? 2) 如果確定只是簡單的展示數(shù)據(jù),用index也是可以的。

    6 React應(yīng)用(基于React腳手架)

    6.1 使用create-react-app創(chuàng)建react應(yīng)用

    6.1.1 react腳手架

  • xxx腳手架: 用來幫助程序員快速創(chuàng)建一個(gè)基于xxx庫的模板項(xiàng)目
    1)包含了所有需要的配置(語法檢查、jsx編譯、devServer…)

    2) 下載好了所有相關(guān)的依賴、

    3)可以直接運(yùn)行一個(gè)簡單效果

  • react提供了一個(gè)用于創(chuàng)建react項(xiàng)目的腳手架庫: create-react-app

  • 項(xiàng)目的整體技術(shù)架構(gòu)為: react + webpack + es6 + eslint

  • 使用腳手架開發(fā)的項(xiàng)目的特點(diǎn): 模塊化, 組件化, 工程化

  • 6.1.2 創(chuàng)建項(xiàng)目并啟動(dòng)

    第一步,全局安裝:npm i -g create-react-app

    第二步,切換到想創(chuàng)項(xiàng)目的目錄,使用命令:create-react-app hello-react

    第三步,進(jìn)入項(xiàng)目文件夾:cd hello-react

    第四步,啟動(dòng)項(xiàng)目:npm start

    6.1.3 react腳手架項(xiàng)目結(jié)構(gòu)

    public ---- 靜態(tài)資源文件夾

    ? favicon.icon ------ 網(wǎng)站頁簽圖標(biāo)(一定要是icon格式)

    ? index.html -------- 主頁面(整個(gè)項(xiàng)目只有這一個(gè)html文件,SPA應(yīng)用,即單頁面應(yīng)用)

    ? logo192.png ------- logo圖

    ? logo512.png ------- logo圖

    ? manifest.json ----- 應(yīng)用加殼的配置文件

    ? robots.txt -------- 爬蟲協(xié)議文件

    src ---- 源碼文件夾

    ? App.css -------- App組件的樣式

    ? App.js --------- App 組件

    ? App.test.js ---- 用于給App做測試(幾乎不用)

    ? index.css ------ 樣式

    ? index.js ------- 入口文件

    ? logo.svg ------- logo圖

    ? reportWebVitals.js

    ? — 頁面性能分析文件(需要web-vitals庫的支持)

    ? setupTests.js

    ? ---- 組件單元測試的文件(需要jest-dom庫的支持)

    6.1.4 功能界面的組件化編碼流程(通用)

  • 拆分組件: 拆分界面,抽取組件

  • 實(shí)現(xiàn)靜態(tài)組件: 使用組件實(shí)現(xiàn)靜態(tài)頁面效果

  • 實(shí)現(xiàn)動(dòng)態(tài)組件

    ? 3.1 動(dòng)態(tài)顯示初始化數(shù)據(jù)

    ? 3.1.1 數(shù)據(jù)類型

    ? 3.1.2 數(shù)據(jù)名稱

    ? 3.1.3 保存在哪個(gè)組件?

    ? 3.2 交互(從綁定事件監(jiān)聽開始)

  • 6.2 react ajax

    6.2.1 理解

  • 注意
    • React本身只關(guān)注于界面, 并不包含發(fā)送ajax請求的代碼

    • 前端應(yīng)用需要通過ajax請求與后臺進(jìn)行交互(json數(shù)據(jù))

    • react應(yīng)用中需要集成第三方ajax庫(或自己封裝)

  • 常用的ajax請求庫
    • Query: 比較重, 如果需要另外引入不建議使用

    • axios: 輕量級, 建議使用

    ? 1) 封裝XmlHttpRequest對象的ajax

    ? 2) promise風(fēng)格

    ? 3) 可以用在瀏覽器端和node服務(wù)器端

    6.2.2 axios

  • 文檔
  • 相關(guān)API
    • GET請求

      axios.get('/user?ID=12345').then(function (response) {console.log(response.data);}).catch(function (error) {console.log(error);});

    axios.get(’/user’, {
    params: {
    ID: 12345
    }
    })
    .then(function (response) {
    console.log(response);
    })
    .catch(function (error) {
    console.log(error);
    });

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • POST請求

      axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      6.2.3 react腳手架配置代理總結(jié)

    • 方法1

      ? 在package.json中追加如下配置

      "proxy":"http://localhost:5000"
      • 1

      ? 說明:

      ? 1)優(yōu)點(diǎn):配置簡單,前端請求資源時(shí)可以不加任何前綴。

      ? 2)缺點(diǎn):不能配置多個(gè)代理。

      ? 3)工作方式:上述方式配置代理,當(dāng)請求了3000不存在的資源時(shí),那么該請求會轉(zhuǎn)發(fā)給5000 (優(yōu)先匹配前端資源)

    • 方法2:

      ? 1)第一步:創(chuàng)建代理配置文件

      ? 在src下創(chuàng)建配置文件:src/setupProxy.js

      ? 2) 編寫setupProxy.js配置具體代理規(guī)則:

      const proxy = require('http-proxy-middleware')
    • module.exports = function(app) {
      app.use(
      proxy(’/api1’, { //api1是需要轉(zhuǎn)發(fā)的請求(所有帶有/api1前綴的請求都會轉(zhuǎn)發(fā)給5000)
      target: ‘http://localhost:5000’, //配置轉(zhuǎn)發(fā)目標(biāo)地址(能返回?cái)?shù)據(jù)的服務(wù)器地址)
      changeOrigin: true, //控制服務(wù)器接收到的請求頭中host字段的值
      /*
      changeOrigin設(shè)置為true時(shí),服務(wù)器收到的請求頭中的host為:localhost:5000
      changeOrigin設(shè)置為false時(shí),服務(wù)器收到的請求頭中的host為:localhost:3000
      changeOrigin默認(rèn)值為false,但我們一般將changeOrigin值設(shè)為true
      */

      pathRewrite: {’^/api1’: ‘’} //去除請求前綴,保證交給后臺服務(wù)器的是正常請求地址(必須配置)
      }),
      proxy(’/api2’, {
      target: ‘http://localhost:5001’,
      changeOrigin: true,
      pathRewrite: {’^/api2’: ‘’}
      })
      )
      }

      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21

      ? 說明:

    • 優(yōu)點(diǎn):可以配置多個(gè)代理,可以靈活的控制請求是否走代理。
    • 缺點(diǎn):配置繁瑣,前端請求資源時(shí)必須加前綴。
    • 6.2.4 消息訂閱-發(fā)布機(jī)制

    • 工具庫: PubSubJS

    • 下載: npm install pubsub-js --save

    • 使用:

      ? 1) import PubSub from ‘pubsub-js’ //引入

      ? 2) PubSub.subscribe(‘delete’, function(data){ }); //訂閱

      ? 3) PubSub.publish(‘delete’, data) //發(fā)布消息

    • 理解

      ? 1)先訂閱,再發(fā)布(理解:有一種隔空對話的感覺)

      ? 2)適用于任意組件間通信

    • ? 3)要在組件的componentWillUnmount中取消訂閱

      6.2.5 擴(kuò)展:Fetch(關(guān)注分離思想)

    • 文檔

      1) https://github.github.io/fetch/

      2) https://segmentfault.com/a/1190000003810652

    • 特點(diǎn)

      1)fetch: 原生函數(shù),不再使用XmlHttpRequest對象提交ajax請求(axios和jQuery都是對XmlHttpRequset的封裝)

      2)老版本瀏覽器可能不支持

    • 相關(guān)API

      1)GET請求

      fetch(url).then(function(response) {return response.json()}).then(function(data) {console.log(data)}).catch(function(e) {console.log(e)});
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      2)POST請求

      fetch(url, {method: "POST",body: JSON.stringify(data),}).then(function(data) {console.log(data)}).catch(function(e) {console.log(e)})
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      7 React路由

      7.1 相關(guān)理解

      7.1.1 SPA 的理解

    • 單頁Web應(yīng)用(single page web application,SPA)。

    • 整個(gè)應(yīng)用只有==一個(gè)完整的頁面==。

    • 點(diǎn)擊頁面中的鏈接==不會刷新頁面,只會做頁面的局部更新。==

    • 數(shù)據(jù)都需要通過ajax請求獲取, 并在前端異步展現(xiàn)。

    • 7.1.2 路由的理解

      1. 什么是路由?

      • 一個(gè)路由就是一個(gè)映射關(guān)系(key:value)

      • key為路徑, value可能是function或component

      2. 路由分類

      ? 1) 后端路由:

      • 理解: value是function, 用來處理客戶端提交的請求。

      • 注冊路由: router.get(path, function(req, res))

      • 工作過程:當(dāng)node接收到一個(gè)請求時(shí), 根據(jù)請求路徑找到匹配的路由, 調(diào)用路由中的函數(shù)來處理請求, 返回響應(yīng)數(shù)據(jù)

      ? 2) 前端路由:

      • 瀏覽器端路由,value是component,用于展示頁面內(nèi)容。

      • 注冊路由:

      • 工作過程:當(dāng)瀏覽器的path變?yōu)?test時(shí), 當(dāng)前路由組件就會變?yōu)門est組件

      7.1 .3 react-router-dom的理解

    • react的一個(gè)插件庫。

    • 專門用來實(shí)現(xiàn)一個(gè)SPA應(yīng)用。

    • 基于react的項(xiàng)目基本都會用到此庫。

    • 7.2 react-router-dom相關(guān)API

      7.2.1 內(nèi)置組件

    • < BrowserRouter >

    • < HashRouter >

    • < Route >

    • < Redirect >

    • < Link >

    • < NavLink >

    • < Switch >

    • 7.2.2. 其它

    • history對象

    • match對象

    • withRouter函數(shù)

    • 8 代碼

      里面由筆記的markdown版本和源代碼,還有一些其他的學(xué)習(xí)筆記
      GitHub地址

      9 參考

      尚硅谷React全家桶
      ps:張?zhí)煊砝蠋熤v得超級棒,yysd

    總結(jié)

    以上是生活随笔為你收集整理的react自看的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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