回文章列表

Modern React 新手補給站(1)-React的基本認識

新手補給站(1)-React的基本認識

前端的工作就是切板,這已經是將近十年前的觀念,隨著現代硬體設備越來越強、網路速度越來越快,瀏覽器能做的事情,已經比便利商店提供的服務還要多樣化,這也造成了前端要掌控的狀態越來越複雜,當開發的專案複雜度大於某個量級的時候,維護起來會變得異常困難,這時候開始有各種前端框架跳出來,想要解決這個事情,最有名的就屬 angular, react, vue 這三個了,這三個被工程師們譽為前端三大框架,而我們今天的主題就是 react。

除了以往的樣式特效以外,現在的前端瀏覽器能做的事情有:
  * 3D 製圖
  * 遊戲
  * 機器學習
  * 接收麥克風音訊
  * 接收鏡頭的視訊
  * VR
  * AR

React 是什麼

要了解這個問題,最快的方式就是去看 React 的官網,畢竟沒有人說的話會比官網還權威,一進到官網就能看到官方給自己下的定義:

A JavaScript library for building user interfaces

A JavaScript library for building user interfaces(創造使用者介面的一個 javascript 函式庫)

有的同學可能就納悶了,原生 js 不是也能做到創造 DOM,或是修改 DOM 的 class 之類的介面處理嘛,其實 js 的確能做到這些事情,畢竟九成以上的 library 都是用 js 寫的,使用這些 library 為的除了不重複造輪子之外,不外乎就是為了更好的開發體驗,

簡單的案例

假如現在有一段 html,我們需要實作 changeFooText() 的功能

<!--html-->
<div id ='fooId'>foo</div>
<button onclick='changeFooText()'>click me</button>

假設現在已經有一個寫好的 function 叫做 getText ,它會根據商業邏輯回傳一個字串,需求是希望點擊 button 後,會去 call getTextApi 並用回傳值,修改上面的foo,那麼我們該怎麼實作這個需求呢?若是寫原生的 js 我們可能會這樣寫

//純 javascript
function changeFooText(){
  const fooDom = document.getElementById('fooId');
  let bar = getText('bar');
  fooDom.innerText=bar;
}

首先要去取得 DOM 再去 call function 來修改它的內容,看起來是簡單又合理的操作,把以上程式碼轉換成 react 的話,大概會長得像是下面這個樣子

// react
class Demo extends React.Component {
  state = { text: "foo" };

  changeFooText = function(){
    let bar = getText('bar');
    this.setState({ text: bar });
  }
  render() {
    return (
      <>
      <div>{this.state.text}</div>
        <button
          onClick={changeFooText}
        >
          click me
        </button>
      </>
    );
  }
}

如果有看不懂的部分可以先不用理會沒有關係,後面幾個章節會詳細解釋 react 基本語法,首先要注意到的是原本 <div id ='fooId'>foo</div> 中的 foo 文字,被替換成了 {this.state.text} 而這裡就會對應到上面 { text: "foo" }; 中的 foo ,如此一來只要修改 state.text,畫面就會改變了,所以在 changeFooText 中,我們就不用再去 get DOM,而是直接去更改 state 就好,不過這個範例比較沒什麼 feel,實際上如果你的專案都是類似這種規模的場景,並沒有使用 react 的意義,我們可以稍微把上面這個案例,稍微變得複雜一點點

細心的讀者可能會發現 html 檔消失了,然後被寫在 js 檔之中,其實那個東西不是 html 而是一個叫做 jsx 的東西,不過不知道這是什麼的同學可以先想像成 react 把 html 寫在 js 裡面了,我們後面幾個章節會在講解 jsx

稍微複雜一點點的案例

跟剛剛一樣我們有一份 html,這次需要實作 changeFoo() 的功能

<!--html-->
<div id ='foo'>
  <div id ='fooId'>foo</div>
  <div id ='fooTitle'>foo</div>
  <div id ='fooDesc'>foo</div>
  <div id ='fooNumber'>foo</div>
  <div id ='fooItem'>foo</div>
  <div id ='fooHead'>foo</div>
  <div id ='fooBody'>foo</div>
</div>
<button onclick='changeFoo()'>click me</button>

我們擁有另一個 function getInfo ,不同的是它這次會回傳的是一個 Object,需要根據這個 Object 來修改裡面全部的資料,不過我們完全可以依樣畫葫蘆,來完成這個需求

// 純 javascript
function changeFoo(){
  const fooIdDom = document.getElementById('fooId');
  const fooTitleDom = document.getElementById('fooTitle');
  const fooDescDom = document.getElementById('fooDesc');
  const fooNumberDom = document.getElementById('fooNumber');
  const fooItemDom = document.getElementById('fooItem');
  const fooHeadDom = document.getElementById('fooHead');
  const fooBodyDom = document.getElementById('fooBody');
  let barInfo = getInfo('bar');
  fooIdDom.innerText = barInfo.id;
  fooTitleDom.innerText = barInfo.title;
  fooDescDom.innerText = barInfo.desc;
  fooNumberDom.innerText = barInfo.number;
  fooItemDom.innerText = barInfo.item;
  fooHeadDom.innerText = barInfo.head;
  fooBodyDom.innerText = barInfo.body;
}

其實整體的邏輯跟剛剛一樣,但是因為我們要改很多不同的 DOM 所以就要 get 每一個 DOM,再對每一個 DOM 去做操作,看起來做了很多相同的事情,再來我們來看看 react 的表現

// react
class Demo extends React.Component {
  state = {
    fooId: "foo",
    fooTitle: "foo",
    fooDesc: "foo",
    fooNumber: "foo",
    fooItem: "foo",
    fooHead: "foo",
    fooBody: "foo",
  };
  changeFoo = function(){
    let fooInfo = getFooApi('bar');
    this.setState({ 
      fooId: fooInfo.id,
      fooTitle: fooInfo.title,
      fooDesc: fooInfo.desc,
      fooNumber: fooInfo.number,
      fooItem: fooInfo.item,
      fooHead: fooInfo.head,
      fooBody: fooInfo.body,
    });
  }
  render() {
    return (
      <>
        <div>
          <div>{this.state.fooId}</div>
          <div>{this.state.fooTitle}</div>
          <div>{this.state.fooDesc}</div>
          <div>{this.state.fooNumber}</div>
          <div>{this.state.fooItem}</div>
          <div>{this.state.fooHead}</div>
          <div>{this.state.fooBody}</div>
        </div>
        <button
          onClick={changeFoo}
        >
          click me
        </button>
      </div>
    );
  }
}

開發者只需要確認資料是對的,然後把他塞到 state 裡面,不需要去 get DOM,react 就會幫你畫好畫面了,開發體驗上,react 明顯略勝一籌,越複雜的專案,使用 react 所帶來的好處就越明顯。

結尾

我在 codeSandBox 開了一個最純粹的 react 專案,非常推薦沒玩過的同學可以自己點開來改改看 state ,絕對能有更多的收穫。

codeSandBox

發表於 Aug 1, 2019

You cannot improve your past, but you can improve your future.Ryan Chu on Github