iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
Modern Web

你 React 了嗎? 30 天解鎖 React 技能系列 第 10

[DAY 10] useState 狀態更新,我要加 1 再加 1!

  • 分享至 

  • xImage
  •  

[情境任務]

叮咚~!! 有客人進門了!

解師傅:歡迎光臨~這是我們的菜單,要點餐再跟我們說一下~

客人:老闆,你們這菜單怎麼連個數量都沒有啊!!叫我怎麼點呢!

解師傅:阿~~不好意思,我馬上調整!!

上回我們把菜單都給列出來了,但客人想要不只一盤啊!來做個數量欄位吧!


cover

認識 useState

State 代表狀態,useState 是用於管理狀態的 Hook,你可以宣告 state 初始值,並對它進行變更修改,使用 state 進行操作達成想要呈現的畫面


useState 使用方法

  • 從 react 中載入 useState
  • 宣告狀態變數、設定狀態的函式
  • 變更 state 狀態
  • 如狀態為集合型態,需合併沒更新的 state

1. 從 react 中載入 useState

import { useState } from 'react';

引入 useState 讓整個組件可以使用 useState hook

2. 宣告狀態變數、設定狀態的函式

const [state, setState] = useState(initValue);

state:狀態變數

setState:改變 state 值的函式,可以為任何命名,不過一般會以「set + 狀態變數」的規則命名

initValue:狀態初始值,可以是任何型態

const [couter, setCouter] = useState(0);

const [userName, setUserName] = useState('Lala');

const [animal, setAnimal] = useState([
  { name: 'cat', age: 12},
  { name: 'dog', age: 6},
  { name: 'mouse', age: 1},
]);

透過解構將 useState 陣列中的值個別取出來,useState 因執行順序,通常會放在函式的最上面,一個組件可以有多個 useState

3. 變更 state 狀態

setState(2);
setState(true);
setState("Lala");
setState(prevValue => prevValue + 1);

setState 裡面會傳入「變更後的值」,可以是一個純值,也可以是一個函式的回傳

為什麼要用函式回傳?

如果我們需要前一次 state 的值,那就需要用函式的方式回傳
由於 setState 是「非同步操作」,我們不能期待連續的 setState 內容會立刻更新,因此將原本傳入的狀態初始值改成傳入一個函式,這個函式參數吃的是原來的 state,以上面的範例來看,state 會等於「原來的 state」 + 1

4. 如狀態為集合型態,需合併沒更新的 state

import { useState } from 'react';

const App = () => {
  const [{count1, count2}, setCount] = useState({count1: 0, count2: 10});
  const addCount1 = () => {
    setCount(state => ({...state, count1: state.count1 + 1}));
  }

  return (
    <div>
      <h1>{ count1 }</h1>
			<h1>{ count2}</h1>
      <button onClick={addCount1}>add</button>
    </div>
  );
}

export default App;

特別注意的是,如果狀態為一個集合 (object、Array)

setState 需要把原本沒使用到的 state 也合併,否則會出錯


[任務解題]

幫菜單加上數量欄位,我要加 1 再加 1

試著做一個計數器,在 components 資料夾新增一個 Counter.js 組件

components/Counter.js

import { useState } from "react";

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

  const addCount = () => {
    setCount(state => state + 1)
  }

  const reduceCount = () => {
    setCount(state => state - 1)
  }

  return (
    <span>
      <button type='button' onClick={addCount}>+</button>
      <button type='button' onClick={reduceCount}>-</button>
	  <span>{count}</span>
    </span>
  );
}

export default Counter;

組件裡面有 +- 的按鈕,用點擊來控制數量

components/List.js

import Counter from "./Counter";

const List = (props) => {
  const { name, price, index } = props;
  return (
    <li>
      <span>{index + 1}.</span>
      <span>{name}</span>
      <span>${price}</span>
      <Counter />
    </li>
  );
};

export default List;

因為每個項目都需要數量,在 List 的地方引入 Counter

App.js

import List from "./components/List";

function App() {
  const menu = [
    { name: "蘆筍沙拉", price: 100 },
    { name: "辣炒空心菜", price: 120 },
    { name: "雞蛋豆腐", price: 150 },
    { name: "鳳梨蝦球", price: 300 },
    { name: "糖醋雞丁", price: 200 },
    { name: "砂鍋魚頭", price: 500 },
    { name: "竹筍炒肉絲", price: 150 },
    { name: "梨山高麗菜", price: 120 },
    { name: "五更腸旺", price: 250 },
    { name: "客家小炒", price: 250 },
    { name: "三杯杏鮑菇", price: 180 }
  ];

  return (
    <div className="App">
      <h1>React 熱炒店</h1>
      <ul>
        {menu.map((item, index) => (
          <List
            key={item.name}
            name={item.name}
            price={item.price}
            index={index}
          ></List>
        ))}
      </ul>
    </div>
  );
}

export default App;

App 原先就有引入 List,維持不變


demo

codesandbox 程式碼範例
數量要多少都可以,這下子可以順利的點餐了!祝福 React 熱炒店生意欣隆/images/emoticon/emoticon42.gif

結語

useState 可以定義狀態、更新狀態,且可以為任何型態,管理起來方便很多,明天我們再繼續吧!


本文將同步更新至我的部落格
Lala 的前端大補帖



上一篇
[DAY 9] 事件處理 - 我這人很簡單,有打卡就給讚
下一篇
[DAY 11] 設定樣式 CSS 與 Style,美化你的網站
系列文
你 React 了嗎? 30 天解鎖 React 技能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言