[情境任務]
叮咚~!! 有客人進門了!
解師傅:歡迎光臨~這是我們的菜單,要點餐再跟我們說一下~
客人:老闆,你們這菜單怎麼連個數量都沒有啊!!叫我怎麼點呢!
解師傅:阿~~不好意思,我馬上調整!!
上回我們把菜單都給列出來了,但客人想要不只一盤啊!來做個數量欄位吧!
認識 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 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住
如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!
Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。