Lala Code

Lala 的前端大補帖,歡迎一起鑽研前端技術😊

0%

【DAY 10】useState 狀態更新,我要加 1 再加 1!

cover

[情境任務]

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

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

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

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

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


認識 useState

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



useState 使用方法

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


1. 從 react 中載入 useState

1
import { useState } from 'react';

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



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

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

state:狀態變數

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

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

1
2
3
4
5
6
7
8
9
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 狀態

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

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

為什麼要用函式回傳?

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



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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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,維持不變




數量要多少都可以,這下子可以順利的點餐了!祝福 React 熱炒店生意欣隆!

結語

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


本文為 IT 鐵人賽系列文 你 React 了嗎? 30 天解鎖 React 技能




Hey!想學習更多前端知識嗎?

最近 Lala 開了前端課程 👉【實地掌握RWD - 12小時新手實戰班】👈
無論您是 0 基礎新手,又或是想學 RWD 的初學者,
我們將帶你從零開始,深入了解並掌握 RWD 響應式網頁設計的核心技術,快來一起看看吧 😊



🚀線上課程分享

線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。

Hahow

Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住



六角學院

如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!


Udemy

Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。
❤️