iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0

為了方便理解,我們今天就用計數器來解釋這個 Hook

https://ithelp.ithome.com.tw/upload/images/20230920/201509478wTltcX4d6.png

如果用香草 js 來寫的話,

會需要找 DOM 元素,並且設定監聽事件,

雖然以計數器這個例子來說,應該不會太難寫,

不過如果功能開始變複雜,在抓取 DOM 元素及設定事件上就會變得很繁瑣。

React 提供了 useState 這個方法給我們

useState 在做什麼?

useState 用於管理一個變數的狀態,我們會在一開始設定初始值給他

在動作觸發後,會根據方法來更新變數的值

useState 該怎麼使用呢?

我們就拿計數器這個例子來操作一次

step 1. 設定變數

我們的數字需要隨著按加按減而變化,這邊我們就用變數帶入

const [count, setCount] = useState(0);

count 表示要定義的變數名稱
setCount 表示動作發生時要觸發的方法名稱
useState 我們要給一個參數,這個參數是變數的初始值

import { useState } from "react";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <button>-</button>
      <div>0</div>
      <button>+</button>
    </div>
  );
}

export default App;

step 2. 用變數取代計時器的數字

在 JSX 中,用大括號就會被判定為 JS 程式碼,所以不管是變數還是方法,都要用 {} 來帶入

import { useState } from "react";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);
  return (
    <div className="counter">
      <button>-</button>
      <div>{count}</div>
      <button>+</button>
    </div>
  );
}

export default App;

step 3. 將觸發動作及觸發方法帶入

當我們點下 + 或者 - 按鈕時,計數器就需要去計算,

我們必須在按鈕埋入事件

動作為點擊,所以放 onClick
事件為我們一開始就定義好的 setCount,並且在裡面寫計算式

import { useState } from "react";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);
  return (
    <div className="counter">
      <button className="button" onClick={() => setCount(count - 1)}>
        -
      </button>
      <div className="number">{count}</div>
      <button className="button" onClick={() => setCount(count + 1)}>
        +
      </button>
    </div>
  );
}

export default App;

這樣我們就完成計數器的初步動作了

不過把計算是寫在 JSX 上不是理想的做法,萬一今天頁面有一堆互動,那 JSX 就會變得很冗長而且不易讀,我們把他收到一個 function 中

step 4. 將 setCount 整理成一個 function

搬移完畢後,記得要把 onClick 後面接的方法改掉

不過,要怎麼知道他到底是要加還是要減?

import { useState } from "react";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);

  function changeCount() {
    setCount()
  }
  
  return (
    <div className="counter">
      <button className="button" onClick={changeCount}>
        -
      </div>
      <div className="number">{count}</div>
      <button className="button" onClick={changeCount}>
        +
      </div>
    </div>
  );
}

export default App;

step 5. 給 JSX 一個 id 來辨認

import { useState } from "react";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);

  function changeCount() {
    setCount()
  }
  
  return (
    <div className="counter">
      <button className="button" id="reducer" onClick={changeCount}>
        -
      </div>
      <div className="number">{count}</div>
      <button className="button" id="addition" onClick={changeCount}>
        +
      </div>
    </div>
  );
}

export default App;

step 6. 用 id 來判斷是要加還是要減

此時我們就可以去判斷點選的按鈕 id 是哪個, setCount 就會依著去計算

import { useState } from "react";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);

  function changeCount(e) {
    if (e.currentTarget.id === "reducer") {
      setCount(count - 1);
    } else {
      setCount(count + 1);
    }
  }
  return (
    <div className="counter">
      <button className="button" id="reducer" onClick={changeCount}>
        -
      </button>
      <div className="number">{count}</div>
      <button className="button" id="addition" onClick={changeCount}>
        +
      </button>
    </div>
  );
}

export default App;

useState 的運作原理

剛剛都有介紹到了,不過我們可以直接看下面這張表來回顧一下

https://ithelp.ithome.com.tw/upload/images/20230920/20150947RR4cVnaCVH.jpg

在 useState 可以學到什麼 JavaScript 原理?

我們今天就來認識解構!

物件及陣列裡面都會包含許多的值,如果要一個一個拿出來還蠻麻煩的,用解構的方式就可以快速地拿到他們!

我們先來看一下原本取出來的用法

const iceCream = {
  name: 'oolong',
  price: 30,
  flavor: 'sweet'
};

假設我們要知道冰淇淋的價錢,需要這樣去取值

const price = iceCreem.price
const name = iceCream.name
const flavor = iceCream.flavor

但如果用解構呢! 一行程式碼就搞定了

const { name, price, flavor } = iceCream

console.log(name) // oolong
console.log(price) // 30
console.log(flavor) // sweet

如果只想取出 name 跟 flavor 呢? {} 裡面只要放兩個就可以了,不過需要注意到順序性

const { name, price } = iceCream

console.log(price) // 30
console.log(flavor) // flavor is not defined

如果只想取第一個跟最後一個,解構目前還沒辦法做到,
用一般的拿取方式可能會比較簡單點。

以上的用法,陣列的應用也是一樣的。

接下來要再介紹一個解構會用到的好東西,展開運算符 ...

const productList = ['tea', 'milk', 'cola', 'juice']

我只想取 tea 跟 juice,那我們可以這樣做

const [ p1, ...p2 ] = productList

console.log(p1) // tea
console.log(p2) // ['milk', 'cola', 'juice']

不過要注意的是 ... 只能用在最後一個


上一篇
Day 04 - 從 Class component 轉變到 Hook
下一篇
Day 06 - React useEffect
系列文
用 React 來認識 JavaScript 的原理概念 - 30 天認識 React 6
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言