邂逅React

簡(jiǎn)介

React是一個(gè)用于構(gòu)建用戶界面的JavaScript庫(kù)

用戶界面User Interface称鳞,簡(jiǎn)稱UI)是系統(tǒng)和用戶之間進(jìn)行交互和信息交換的介質(zhì),在這里指代的就是網(wǎng)頁(yè)前端界面

傳統(tǒng)的JS的問(wèn)題

  1. 需要頻繁的操作DOM欠窒,而操作DOM對(duì)于不同的瀏覽器之間存在一定的兼容性問(wèn)題
  2. 而過(guò)多的兼容性代碼素征,會(huì)在一定程度上造成業(yè)務(wù)邏輯代碼的冗余
  3. 代碼組織和規(guī)范的問(wèn)題
  4. 我們編寫頁(yè)面的時(shí)候崭参,需要過(guò)多的關(guān)注界面的細(xì)節(jié)穆役,也就是說(shuō)我們即需要操作DOM民镜,還需要去管理和維護(hù)頁(yè)面的狀態(tài)(數(shù)據(jù))
  5. 數(shù)據(jù)(狀態(tài))的定義和使用往往會(huì)分散到各個(gè)地方乍桂,不方便管理和維護(hù)

react框架的思想

  1. 以組件的方式去劃分一個(gè)個(gè)功能模塊
  2. 組件內(nèi)以jsx來(lái)描述UI的樣子袜瞬,以state來(lái)存儲(chǔ)組件內(nèi)的狀態(tài)
  3. 當(dāng)應(yīng)用的狀態(tài)發(fā)生改變時(shí)怜俐,通過(guò)setState來(lái)修改狀態(tài),狀態(tài)發(fā)生變化時(shí)邓尤,UI會(huì)自動(dòng)發(fā)生更新

特點(diǎn)

聲明式編程

聲明式編程只需要維護(hù)自己的狀態(tài)拍鲤,當(dāng)狀態(tài)改變時(shí),React可以根據(jù)最新的狀態(tài)去渲染我們的UI界面

在React中汞扎,表示界面的JSX是依賴于state的季稳,

而當(dāng)state發(fā)生改變的時(shí)候,可以使用setState去重新調(diào)用render函數(shù)澈魄,從而重新渲染界面

1.png

在react中景鼠,上述的f函數(shù)就是render函數(shù)

組件化開發(fā)

網(wǎng)站的整體看成是一個(gè)組件,也就是根組件

隨后網(wǎng)頁(yè)根據(jù)功能點(diǎn)進(jìn)行劃分成一個(gè)個(gè)小的組件

最后再通過(guò)打包工具,將這一個(gè)個(gè)小的組件整合起來(lái)

1.png

跨平臺(tái)開發(fā)

  • 2013年铛漓,React發(fā)布之初主要是開發(fā)Web頁(yè)面
  • 2015年溯香,F(xiàn)acebook推出了ReactNative,用于開發(fā)移動(dòng)端跨平臺(tái)
  • 2017年浓恶,F(xiàn)acebook推出ReactVR玫坛,用于開發(fā)虛擬現(xiàn)實(shí)Web應(yīng)用程序

React依賴的庫(kù)

庫(kù) 說(shuō)明
react 包含了react和react-native所共同擁有的核心代碼
react-dom react渲染在不同平臺(tái)所需要的核心代碼
babel 編譯器

react-dom會(huì)根據(jù)需要渲染的平臺(tái),將對(duì)于的vdom渲染成對(duì)應(yīng)的dom或組件

平臺(tái) 說(shuō)明
web端 react-dom會(huì)講jsx最終渲染成真實(shí)的DOM包晰,顯示在瀏覽器中
native端 react-dom會(huì)講jsx最終渲染成原生的控件(比如Android中的Button湿镀,iOS中的UIButton)

babel是目前前端使用非常廣泛的編輯器,

雖然ES6很方便,但是某些老版本瀏覽器不支持ES6伐憾,只支持ES5

babel讓我們可以直接在編寫代碼的時(shí)候使用ES6

在部署的時(shí)候勉痴,會(huì)將我們ES6的代碼轉(zhuǎn)換為ES5的代碼,從而適配我們所有需要適配的瀏覽器

默認(rèn)情況下開發(fā)React其實(shí)可以不使用babel

但是React默認(rèn)情況下需要使用React.createElement來(lái)編寫頁(yè)面結(jié)構(gòu)树肃,

而React.createElement本身編寫是非常繁瑣的和可讀性差

所以React提供了React.createElement的語(yǔ)法糖JSX

默認(rèn)情況下jsx(JavaScript XML)蚀腿,React是無(wú)法直接解析的

所以需要babel將jsx轉(zhuǎn)換為React.createElement形式的代碼后在交給React來(lái)進(jìn)行解析

Hello World

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 全局掛載React對(duì)象 -->
  <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
  <!-- 全局掛載ReactDOM對(duì)象 -->
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
  <!-- 掛載點(diǎn) -->
  <div id="app"></div>

  <!-- type="text/babel" -> 告訴瀏覽器這些腳本要交給babel進(jìn)行解析 -->
  <script type="text/babel">
    // 將參數(shù)1的內(nèi)容掛載到參數(shù)2上,并覆蓋原本掛載點(diǎn)中的內(nèi)容
    // 參數(shù)1 -- JSX對(duì)象 需要渲染的內(nèi)容 經(jīng)過(guò)React.createElement處理后返回ReactRenderObject對(duì)象  也就是VDom對(duì)象
    // 參數(shù)2 --- 掛載點(diǎn)
    ReactDOM.render(<h2>Hello World</h2>, document.getElementById('app'))
  </script>
</body>
</html>

命令式編程 vs 聲明式編程

示例

  1. 在界面顯示一個(gè)文本: Hello World
  2. 點(diǎn)擊下方的一個(gè)按鈕扫外,點(diǎn)擊后文本改變?yōu)镠ello React

命令式編程

<!--
  這種即需要關(guān)心頁(yè)面狀態(tài)又需要關(guān)心模板
  還需要在界面發(fā)生改變的時(shí)候,手動(dòng)去操作DOM來(lái)更新界面的編程范式就被稱之為響應(yīng)式編程
  響應(yīng)式編程的本質(zhì)就是每一步都是向?yàn)g覽器發(fā)送一條條的指令廓脆,凡事都是親力親為的
-->
<div id="app">
  <h2 id="msg"></h2>
  <button id="btn">change</button>
</div>

<script type="text/babel">
    let msg = 'Hello World'

    const msgEl = document.getElementById('msg')
    const btnEl = document.getElementById('btn')

    msgEl.innerHTML = msg

    btnEl.addEventListener('click', () => {
      msg = 'Hello React'
      msgEl.innerHTML = msg
    })
</script>

聲明式編程

let msg = 'Hello World'

function render() {
  // 使用小括號(hào)是為了表示成一個(gè)整體筛谚,同時(shí)可以進(jìn)行換行顯示
  const jsx = (
    // JSX有且只能有一個(gè)根元素
    <div>
      {/* 使用大括號(hào)語(yǔ)法來(lái)插入變量 */}
      <h2>{msg}</h2>
      {/* 在react中原生事件使用小駝峰,因?yàn)閞eact對(duì)原生事件進(jìn)行了二次封裝 */}
      <button onClick={ handleChange }>change</button>
    </div>
  )

  ReactDOM.render(jsx, document.getElementById('app'))
}

function handleChange() {
  msg = 'Hello React'
  render()
}

// 初始化渲染
render()

但是上邊的代碼看起來(lái)有點(diǎn)凌亂停忿,且整個(gè)邏輯其實(shí)可以看做一個(gè)整體驾讲,也就是整個(gè)邏輯本身就可以看成是一個(gè)功能點(diǎn),即整個(gè)邏輯其實(shí)可以封裝為一個(gè)組件席赂,也就是根組件

// 這種只要定義模板和狀態(tài)即可吮铭,不需要我們頻繁的去操作DOM的編程范式就是響應(yīng)式編程

// 一個(gè)類繼承自React.Component后就成為了React組件
class App extends React.Component {
  constructor() {
    // 繼承類必須在構(gòu)造器的第一行調(diào)用super方法
    // 以初始化父類實(shí)例
    super()
    // 如果定義的對(duì)象是需要響應(yīng)式的對(duì)象
    // 也就是那些當(dāng)值發(fā)生改變后,界面也需要相應(yīng)發(fā)生刷新的那些對(duì)象
    // 在定義這些響應(yīng)式對(duì)象的時(shí)候颅停,必須定義在state對(duì)象中
    this.state = {
      msg: 'Hello World'
    }
  }


  // 組件必須實(shí)現(xiàn)一個(gè)render函數(shù)
  // 該函數(shù)需要返回對(duì)應(yīng)的jsx對(duì)象
  // 用于告訴React需要顯示的template
  render() {
    // 如果return后邊的div需要和return分兩行來(lái)進(jìn)行編寫
    // 就需要給div外包裹小括號(hào)谓晌,以表示這是個(gè)整體
    return (
      <div>
        {/* render不是react中的原生函數(shù),所以其內(nèi)部的this指向是正確的 */}
        <h2>{this.state.msg}</h2>
        <button onClick={ this.handleChange }>change</button>
      </div>
    )
  }

  // 默認(rèn)情況下癞揉,React內(nèi)置的原生事件在調(diào)用的時(shí)候纸肉,會(huì)將原生事件中的this置為undefined
  // 所以我們需要使用箭頭函數(shù)進(jìn)行重置
  handleChange = () => {
    // render函數(shù)本質(zhì)是返回JSX對(duì)象
    // 但是單獨(dú)調(diào)用render函數(shù)并不會(huì)將新的JSX交給ReactDOM來(lái)重新渲染
    // 所以在更新響應(yīng)式數(shù)據(jù)的時(shí)候,必須調(diào)用setState函數(shù)
    // 在實(shí)際開發(fā)中喊熟,我們一般不會(huì)手動(dòng)去調(diào)用render函數(shù)
    // this.render()

    // 響應(yīng)式數(shù)據(jù)發(fā)生改變的時(shí)候
    // 調(diào)用setState方法進(jìn)行界面刷新
    this.setState({
      msg: 'Hello React'
    })
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

簡(jiǎn)單案例

電影列表

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      movies: ['電影1', '電影2', '電影3', '電影4', '電影5']
    }
  }

  render() {
    return (
      <div>
        {/*
          react直接顯示數(shù)組的時(shí)候柏肪,會(huì)主動(dòng)調(diào)用數(shù)組的join方法,分隔符為空字符串
          所以這里實(shí)際展示的是this.state.moives.join('')
        */}
        { this.state.movies }
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

既然react在顯示的時(shí)候芥牌,會(huì)主動(dòng)調(diào)用數(shù)組的join方法烦味,那么我們所需要做的就是為數(shù)組中的每一項(xiàng)包裹li標(biāo)簽即可

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      movies: ['電影1', '電影2', '電影3', '電影4', '電影5']
    }
  }

  render() {
    return (
      <ul>
        {
          this.state.movies.map(moive => <li>{ moive }</li>)
        }
      </ul>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

計(jì)數(shù)器

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      count: 0
    }
  }

  render() {
    return (
      <div>
        <h2>{ this.state.count }</h2>
        <button onClick={() => this.change(1)}>+1</button>
        <button onClick={() => this.change(-1)}>-1</button>
      </div>
    )
  }

  change = step => {
    this.setState({
      count: this.state.count + step
    })
  }
}

ReactDOM.render(<App />, document.getElementById('app'))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市壁拉,隨后出現(xiàn)的幾起案子谬俄,更是在濱河造成了極大的恐慌柏靶,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凤瘦,死亡現(xiàn)場(chǎng)離奇詭異宿礁,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蔬芥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門梆靖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人笔诵,你說(shuō)我怎么就攤上這事返吻。” “怎么了乎婿?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵测僵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我谢翎,道長(zhǎng)捍靠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任森逮,我火速辦了婚禮榨婆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘褒侧。我一直安慰自己良风,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布闷供。 她就那樣靜靜地躺著烟央,像睡著了一般。 火紅的嫁衣襯著肌膚如雪歪脏。 梳的紋絲不亂的頭發(fā)上疑俭,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音婿失,去河邊找鬼怠硼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛移怯,可吹牛的內(nèi)容都是我干的香璃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼舟误,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼葡秒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤眯牧,失蹤者是張志新(化名)和其女友劉穎蹋岩,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體学少,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡剪个,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了版确。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扣囊。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绒疗,靈堂內(nèi)的尸體忽然破棺而出侵歇,到底是詐尸還是另有隱情,我是刑警寧澤吓蘑,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布惕虑,位于F島的核電站,受9級(jí)特大地震影響磨镶,放射性物質(zhì)發(fā)生泄漏溃蔫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一琳猫、第九天 我趴在偏房一處隱蔽的房頂上張望酒唉。 院中可真熱鬧,春花似錦沸移、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至癞蚕,卻和暖如春蕊爵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桦山。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工攒射, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恒水。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓会放,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親钉凌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咧最,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容

  • 邂逅React開發(fā) React是什么? ■React是什么呢?相信每個(gè)做開發(fā)的人對(duì)它都或多或少有一些印象矢沿。 口這...
    songstar閱讀 311評(píng)論 0 0
  • 前言:終于結(jié)束了緊張的一個(gè)學(xué)期滥搭,網(wǎng)課上的挺有趣,就是課程太擠了點(diǎn)捣鲸。這個(gè)暑假瑟匆,就從React開始吧。 一栽惶、為什么學(xué)習(xí)...
    waigo閱讀 286評(píng)論 0 0
  • React框架學(xué)習(xí) React的起源和發(fā)展 起初facebook在建設(shè)instagram(圖片分享)的時(shí)候嘞愁溜,因?yàn)?..
    hcySam閱讀 676評(píng)論 0 1
  • 1. React 特點(diǎn): 聲明式編程:(1) 聲明式編程現(xiàn)在是目前整個(gè)大前端開發(fā)模式: Vue React Flu...
    coderhzc閱讀 1,209評(píng)論 0 1
  • 深入JSX date:20170412筆記原文其實(shí)JSX是React.createElement(componen...
    gaoer1938閱讀 8,073評(píng)論 2 35