React學習-React初識

1、前言javascript

  爲何要去學習React呢,關於前端三大框架Angular,Vue,React其實都得去學吧,由於你們都在用啊,你們都再談論啊,面試什麼的都要求,沒辦法,曾幾什麼時候,你們都說求求大佬們別坑新了,別出框架了,老子孩子孫子都學不動了。其實我jiao的吧,技術,不就是一直更新的,新的技術代替老的技術,說不定有一天,三大框架也會被其餘東西代替,就想之前的jquery同樣,沒什麼的,我以爲大佬們出一個框架的時間,比起咱們去學習的時間來講真的是太多了,這東西思想都是同樣的,都是通的,若是真的去認真學習一下,也就幾天的時間。技多不壓身,就這樣吧。php

    關於爲何要學習React,就說如下幾點吧html

  1. 和Angular1相比,React設計很優秀,一切基於JS而且實現了組件化開發的思想;
  2. 開發團隊實力強悍,沒必要擔憂斷更的狀況;
  3. 社區強大,不少問題都能找到對應的解決方案;
  4. 提供了無縫轉到 ReactNative 上的開發體驗,讓咱們技術能力獲得了拓展;加強了咱們的核心競爭力;
  5. 不少企業中,前端項目的技術選型採用的是React.js;

  其實讓我總結起來就三點:1.用的人多  2.用的人多 3.用的人多前端

2、React中的幾個核心概念vue

  2.1 虛擬DOM(Virtual Document Object Model)

  • DOM的本質是什麼:瀏覽器中的概念,用JS對象來表示 頁面上的元素,並提供了操做 DOM 對象的API;
  • 什麼是React中的虛擬DOM:是框架中的概念,是程序員 用JS對象來模擬 頁面上的 DOM 和 DOM嵌套;
  • 爲何要實現虛擬DOM(虛擬DOM的目的):爲了實現頁面中, DOM 元素的高效更新

  好比咱們的頁面上有一個dom元素,輸出這個dom元素(暫且叫真實的dom元素)java

<body>
    <div id="box" title="這是一個dom元素" data-value="div">
        這是一個文本節點
        <p>p標籤</p>
    </div>
    <script>
        var div = document.getElementById('box');
        console.log(div);
    </script>
</body>

  

  那麼接下來咱們來用虛擬DOM的方法來描述這個dom元素,也就是用一個js對象來表示這個dom元素的全部東西,未來咱們也能用這個虛擬的dom來渲染出來真實的dom   react

<script>
        var div = {
            tagName:'div',//html標籤名
            attrs:{
                id:'box',
                title:'這是一個dom元素',
                'data-value':'div'
            },
            childrens:[
                '這是一個文本節點',
                {
                    tagName:'p',
                    attrs:null,
                    childrens:[
                        'p標籤'
                    ]
                }
            ]
        }
 </script>

  就這樣,咱們就用js對象描述了一個完整的dom元素。jquery

   2.2 Diff算法webpack

  所謂Diff,也就是Different,就是差別的意思,React是比較數據變換先後虛擬dom的差別來更新界面的上dom元素的,而且只是更新改變的dom節點的各項屬性值,不改變的就不去更新。程序員

  在咱們傳統的操做dom的方式中,好比一個集合,當裏邊的某條數據變化,咱們通常會從新賦值集合,而且使用模板引擎從新調用一下渲染方法,這樣一來是更新了所有的dom節點,相比而言就不那麼高效了。

  至於算法到底是怎麼來的咱們也沒必要深究了。也就是對比上邊的兩個js對象,有沒有差別啥的,而後作標記,須要更新那些東西,而後再反饋到界面上。

3、第一個HelloWorld程序

 看了很多教程,上來就是腳手架什麼的 ,一會兒懟一大堆東西,都不知道什麼玩意。也有用webpack的,直接開始模塊化開發,初學者不建議這樣,弄的都是一頭霧水的。其實react,vue,angular這些框架都能和使用jquery同樣,頁面引入相關js就好了,這篇文章最主要的仍是寫給初學者和後端,前端可能就不須要了。

  3.1 首先要引入相關js,博主已經給準備好了,點擊下載lib.zip,頁面代碼以下,也是很是的簡單大氣上檔次: 

  

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="lib/babel.js"></script>
    <script src="lib/react.development.js"></script>
    <script src="lib/react-dom.development.js"></script>
</head>

<body>
    <div id="app"></div>
    <script>
        console.log(React, ReactDOM);
    </script>
</body>

</html>

  很簡單,和你剛學jquery是同樣的,引入以後輸出一下React的兩個對象,沒問題就能夠開始了。

  3.2 建立虛擬dom元素,渲染到頁面上

<body>
    <div id="app"></div>
    <script>
        // 這是 建立虛擬DOM元素的 API    <h1 title="h1標籤" id="myh1">hello world</h1>
        //  第一個參數: 字符串類型的參數,表示要建立的標籤的名稱
        //  第二個參數:對象類型的參數, 表示 建立的元素的屬性節點
        //  第三個參數: 子節點
        var h1 = React.createElement('h1', { title: 'h1標籤', id: 'myh1' }, 'hello world')

        // 3. 渲染虛擬DOM元素
        // 參數1: 表示要渲染的虛擬DOM對象
        // 參數2: 指定容器,注意:這裏不能直接放 容器元素的Id字符串,須要放一個容器的DOM對象
        ReactDOM.render(h1, document.getElementById('app'))
    </script>
</body>

  運行結果以下:

  

 4、JSX語法

  4.1 html代碼和js代碼混編

  建立虛擬dom着實麻煩,若是有嵌套狀況就更麻煩了,要寫好半天,因而React提供了一套新的建立虛擬dom的方法,這是一新語法,意思就是js的擴展語法,可讓咱們直接在js代碼中寫html標籤和js代碼,意思就是js和html代碼混寫。引用李納斯的一句名言:talk is cheap,show me your code,不懂的話,翻譯成漢語就是:廢話少說,放碼過來。

<body>
    <div id="app"></div>
    <script>
        var h1 = <h1 title="h1標籤" id="myh1">hello world</h1>; //沒錯,就是這樣直接寫標籤,不加'',不是字符串
        ReactDOM.render(h1, document.getElementById('app'))
    </script>
</body>

  運行結果以下:

  

  沒錯,報錯了,由於  var h1 = <h1 title="h1標籤" id="myh1">hello world</h1>; 是新語法,如今好多瀏覽器根本不認識,因此確定報錯。別忘了,咱們以前還引入了一文件就是babel.js,這貨就是用來幫瀏覽器來認這樣的代碼的,另外還有一些很新的es6的語法,瀏覽器也不認識,也須要它的幫助。

  接下來咱們就來使用它,就是把<script></script>標籤 改爲 <script type="text/babel"></script>,text/babel就是 babel.js來識別的,它會把裏邊的高級代碼轉換成瀏覽器能認識的代碼,自己這段script 瀏覽器看見他的type屬性是不認識的,因此不會管它。

  修改以後以下:

  

  4.2 加入js代碼(數據處理)

   接下來咱們寫點js代碼,渲染一些數據,爲了區別在html標籤中的js代碼,須要用{} 把js代碼包起來,這個語法好多模板框架都有,vue,angular裏邊是{{}} ,也都相似,都差很少。咱們來渲染一個列表

<body>
    <div id="app"></div>
    <script type="text/babel">
    // jsx語法下的數組
    var fruits = [
      <li key="1">蘋果</li>, 
      <li key="2">香蕉</li>,
      <li key="3">橘子</li>
    ] 

    // js語法下的數組 
    var todos = [
      {
        id: 1,
        title: '吃飯'
      },
      {
        id: 2,
        title: 'sleep'
      },
      {
        id: 3,
        title: ''
      }
    ]
 
    // 調用map方法 生成一個jsx數組 
    var todoLis = todos.map(item => {
      return <li key={item.id}>{item.title}</li>
    }) 
    
    // 推薦jsx語法中元素用括號包起來 
    var element = (
      <div>
        {/* 在 jsx 中,綁定數組成員會直接把成員渲染到這裏 (jsx中的註釋要寫在花括號)  */}
        <ul>{fruits}</ul>
        <ul>
          {/* 直接綁定一個數據 */}
          {todoLis}
        </ul>
        {/* 直接在標籤中動態生成一個數組 */}
        <ul>
          {
            todos.map(item => {
              return <li key={item.id}>{item.title}</li>
            })
          }
        </ul>
      </div>
    )

    ReactDOM.render(element, document.getElementById('app'))
    </script>
</body>

   運行結果以下:

   

   4.3 加入js代碼(事件處理)

    事件名稱和原生事件都同樣,只不過寫法上注意一點大小寫,由於後邊是js代碼,全部用{}包起來

<body>
    <div id="app"></div>
    <script type="text/babel">
        function handleClick () {
             window.alert('hello')
        }

        // 1. 使用駝峯命名
        // 2. 必須綁定一個函數
        // 3. 不能使用字符串的方式,必定要使用 {函數} 來綁定
        var element = (
        <div>
            <button onClick={handleClick}>點我</button>
            {/* 直接綁定一個匿名函數 */}
            <button onClick={() => alert('hello world')}>行內處理</button>
        </div>
        )

         ReactDOM.render(element, document.getElementById('app'))
    </script>
</body>

5、組件化編程

  React最大的特色就是組件化編程,也就是模塊化編程,可是模塊化是對於業務代碼來講的,好比js代碼中一個功能塊,java中的一個utils包,c#中的一個dll類庫,組件化其實也是一個塊,只不是是對於界面上ui來講,好比說一個日曆組件,在界面上展示出來就是一個日曆,不管是模塊化仍是組件化都有一個特色,那就是拿過來到哪裏都能用。組件化編程就是要求咱們把頁面分紅一塊一塊的,這樣一來頁面結構清晰,每個組件控制每一塊頁面,互不影響,固然你有時候也能夠把一個頁面當作一個組件,當這個頁面實在是沒多少東西很簡單的時候就能夠這樣作。

  5.1 函數式組件

   函數式組件使用時,直接定義一個函數,函數名稱大寫,之於爲何大寫,這裏內部React把 一個組件當作一個類了,以後咱們會介紹以類的方式來建立組件,使用的時候在render函數裏邊放一個以函數名 命名的標籤就好了。但標籤和雙標籤都行。

<body>
    <div id="app"></div>
    <script type="text/babel">
        // 組件的名字首字母必須大寫
        function AppHeader () {
            return (
                {/* jsx中若是要給標籤加類名的話,用className屬性,由於class在js代碼中爲關鍵字*/}
                <div className="header">
                <h1>頭部</h1>
                </div>
            )
        }
       
        //使用方式以下 用一個閉合的標籤 單標籤和雙標籤都行
        //ReactDOM.render(<AppHeader></AppHeader>, document.getElementById('app'))
        ReactDOM.render(<AppHeader/>, document.getElementById('app'))
    </script>
</body>

   固然咱們也能夠爲組件傳遞數據,傳遞數據的方式是在標籤上加屬性值,這裏能夠寫js代碼,在組件的函數中會以形參的方式傳遞過來,傳遞過來的數據是隻讀的,咱們並不能做修改

<body>
    <div id="app"></div>
    <script type="text/babel">

        var dog = {
            name:'haha',
            age:5,
            sex:''
        }
        // 組件的名字首字母必須大寫
        function AppHeader (props) {
            //組件上傳遞的數據會做爲形參傳遞過來,形參名字什麼都無所謂,通常咱們props 意思就是屬性
            //可是這個屬性是隻讀的,咱們不能修改
            props.name = '1'
            console.log(props);
            //jsx中若是要給標籤加類名的話,用className屬性,由於class在js代碼中爲關鍵字
            return (
                <div className="header">
                    <h1>頭部,{props.name},{props.age}</h1>
                </div>
            )
        }
       
        //使用方式以下 用一個閉合的標籤 單標籤和雙標籤都行
        //ReactDOM.render(<AppHeader></AppHeader>, document.getElementById('app'))
        //傳遞給AppHeader組件的數據
        ReactDOM.render(<AppHeader name={dog.name} age={dog.age}/>, document.getElementById('app'))
    </script>
</body>

  5.2 class方式建立的組件

  React推薦咱們用class方式建立組件,建立的組件用class關鍵字,而且繼承React.Component,這纔會把這個類標記爲一個組件,在組件中,必須聲明一個render方法,返回jsx元素,內部react會調用這個方法幫咱們渲染組件。 

<body>
    <div id="app"></div>
    <script type="text/babel">
    // 1. class 組件類,必須繼承自 React.Component 纔是一個組件類,不然就是一個普通的類
    // 2. 在組件類中,必須經過 render 渲染函數返回組件模板
    // 3. 接下來就能夠在其它能訪問到這個組件類的做用域中去使用這個組件了
    class MyComponent extends React.Component {
      render () {
        return (
          <div>
            <h1>My Component</h1>
          </div>
        )
      }
    }

    var element = <MyComponent />
    ReactDOM.render(element, document.getElementById('app'))
    </script>
</body>

   既然是class,就會有本身的實例數據,接下來咱們建立一個具備本身私有數據的組件,咱們在class內部定義一個state變量來存儲數據

<body>
    <div id="app"></div>
    <script type="text/babel">
    // EcmaScript 6 Class
    class AppFooter extends React.Component {
      constructor () {
        super()
        // state 就是組件的狀態,也就是把數據驅動視圖的數據初始化到 state 中
        // state 相似於 Vue 中的 data
        this.state = {
          foo: 'bar'
        }
      }
      render () {
        return (
          <div className="footer">
            <p>底部 {this.state.foo}</p>
          </div>
        )
      }
    }

    ReactDOM.render(<AppFooter/>, document.getElementById('app'))
    </script>
</body>

   5.3 兩種方式的對比

   其實咱們上邊以class方式建立的帶有state變量的組件 就叫作有狀態的組件,這中組件有本身的私有數據,不和外邊有接觸,而且數據還能夠更改,這樣咱們就真正實現了組件化,想用的時候隨時隨地拿一個實例就好了。根據實例不一樣的數據渲染成不一樣狀態的組件。

  其實這個state就相似vue中的data了。第一種函數式建立的方法,沒有本身數據,且建立方式過於分離,適合那種簡單且不牽扯到數據變化的靜態純展示的組件。

6、真正的使用組件

    接下來咱們建立一個功能比較完成的商品列表組件,react在渲染列表數據的時候 要給每一個項目添加一個key屬性來保證惟一,這樣的話React更新dom的時候確保每項的狀態一直保證正確,若是不加的話可能會有一些問題。

<body>
    <div id="app"></div>
    <script type="text/babel">
     class ProductList extends React.Component {
      constructor () {
        // 若是子類加入了 constructor 構造函數,則必定要手動調用父類的構造函數 super
        super()
        // React 組件須要經過手動爲組件類添加 state 成員來初始化:ViewModel
        // state 等價於 Vue 中的 data
        // 接下來就能夠在該組件管理的模板中經過 {} 來訪問綁定數據了
        this.state = {
          products:[
              {
                  id:1,
                  name:'iphone x',
                  price:8999
              },
              {
                  id:2,
                  name:'xiao mi 8',
                  price:2999
              }
          ]
        }
      }

      render () {
        return (
          <div>
           <ul>
            {
                this.state.products.map(item => {
                    return (<li key={item.id}>
                        <span>名稱:{item.name}</span>
                        <span>價格:{item.price}</span>
                        <button onClick={this.show.bind(this,item)}>獲取商品</button>
                        <button onClick={this.add.bind(this)}>添加商品</button>
                    </li>)
                })
            }
           </ul>
          </div>
        )
      }
     
      show (item) {
        console.log(item)
        // console.log(this) // 默認是 window 這裏咱們採用this.show.bind(this) 把this指針改爲當前組件
        //這樣咱們就能能用this 調用 當前組件裏的 數據(state)和方法了。
      }
      add(){

        // React 不是使用的相似於 Vue 中的 Object.defineProperty() 方式 get、set
        // this.state.message = 'hello world'
        // React中沒有雙向綁定的功能,(吐槽一下,不知道爲何沒設計,感受這是和vue比較時的一大劣勢)
        // 如今只須要知道,若是要修改 state 中的數據而且但願獲得視圖更新,則必定要使用
        // this.setState 方法
        // this.setState({
        //   message: 'hello world'
        // })
          var products = this.state.products;
          products.push({
              id:products.length+1,
              name:'華爲 p30',
              price:4999
          })
          this.setState({
              products:products
          })
          console.log(this.state)
      }
    }

    ReactDOM.render(<ProductList/>, document.getElementById('app'))
    </script>
</body>

 運行結果以下,點擊相關按鈕可看到結果

  

7、總結

  本篇React教程只是爲了新手和一些後端人員學習,學完以後知道React是什麼就能夠了。其實若是要用React也徹底能夠這麼來用,對於後端人員來講,引入相關js就好了。不過前端確定都用webpack工程化開發,各類配置各類打包至關麻煩。有人說腳手架了,其實腳手架也就是把經常使用的配置給你生成好了。這些都是工具吧,你想用就去學一點,關鍵仍是技術吧。就像前端開發,能用的編輯器不得和你親戚同樣多。

  一直有同窗說,腳手架是什麼東西。腳手架就是框架啊,你本身慢慢一行代碼一行代碼的配也行啊,就好比你搭建ssm框架,mvc框架,三層框架,代碼生成器生成一坨坨的東西。都一個意思。其實我一直很討厭官方定義的一些東西,就好比至今我都不知道socket 爲何叫套接字編程,難道是中國人硬懟過來的。

  感受後端學習這些框架其實很簡單的,由於思想在裏邊,並且前端好多東西其實都在有意無心的日後端轉。我真的以爲React的jsx語法 其實和jsp 或者 aspx ,甚至和php也差很少吧 都是在html代碼中混寫邏輯代碼。

  至於其餘框架,Angular感受實在過重了,其實我更愛vue,各有優缺點吧。反正天下框架一大抄吧,不對,文化人讀書人的事怎能說抄呢,是吸收精華,去其糟粕,吸取外來文化,爲我全部,不要說三大框架,就是各類編程語言裏的框架都能看見裏邊有相同的影子,由於畢竟編程這個思想是同樣的啊,你不滿意,就從新造一個,我不滿意,我也從新寫一個,百度不是還出了一個san,沒什麼好很差吧,用起來舒服就行,能提升效率提升生產力就行。你們都是混口飯吃,何須糾結來糾結去呢,好了就去學就去使用,很差了就換一個。

  算了不扯淡了,不過這是我一向的風格,就算是學習技術的文章,也不想去那麼很嚴肅,很正式,畢竟,學東西都夠累了,還不能吐槽幾句。

相關文章
相關標籤/搜索