React 使用 useState 來管理陣列和物件狀態

更新 發佈閱讀 14 分鐘

基本介紹

在 React 中,使用 useState 來管理陣列和物件狀態時,需要遵循不變性原則

  • 不可直接修改原本的陣列或物件(例如直接改變某個索引或屬性),
  • 必須產生一個新的陣列或物件,再透過 setState 更新。

下面提供大量範例,分別展示如何更新陣列和物件。

新增項目到陣列

import React, { useState } from 'react';

function ArrayAddExample() {
// 初始為空陣列
const [items, setItems] = useState([]);

// 函式:新增項目
const addItem = () => {
const newItem = `Item ${items.length + 1}`;
// 使用展開運算子複製舊陣列,加上新項目
setItems(prevItems => [...prevItems, newItem]);
};

return (
<div>
<button onClick={addItem}>Add Item</button>
<ul>
{items.map((item, index) => (
// index 作為 key(僅供示範,真實專案建議使用獨特 id)
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}

export default ArrayAddExample;
  • 使用展開運算子 [...] 產生新陣列,確保不改變原有陣列。
  • 每次點擊按鈕,將新的項目加到陣列末端。

效果:

raw-image

移除陣列中的項目

import React, { useState } from 'react';

function ArrayRemoveExample() {
const [items, setItems] = useState(["Apple", "Banana", "Cherry"]);

// 根據索引移除項目
const removeItem = (indexToRemove) => {
setItems(prevItems =>
prevItems.filter((item, index) => index !== indexToRemove)
);
};

return (
<div>
<ul>
{items.map((item, index) => (
<li key={index}>
{item}
<button onClick={() => removeItem(index)}>Remove</button>
</li>
))}
</ul>
</div>
);
}

export default ArrayRemoveExample;
  • 使用 filter 方法產生一個不包含指定索引的新陣列,並重新渲染。

現在你可以移除項目清單:

效果:

raw-image

更新物件

更新物件的單一屬性

import React, { useState } from 'react';

function ObjectUpdateExample() {
const [user, setUser] = useState({
name: "John",
age: 25,
email: "john@example.com",
});

// 更新名稱
const updateName = () => {
// 使用展開運算子複製原有物件,並更新 name 屬性
setUser(prevUser => ({ ...prevUser, name: "Jane" }));
};

return (
<div>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
<p>Email: {user.email}</p>
<button onClick={updateName}>Change Name</button>
</div>
);
}

export default ObjectUpdateExample;
  • 使用展開運算子 { ...prevUser } 產生新物件,然後覆蓋 name 屬性,確保其他屬性保持不變。

更新嵌套物件中的值

當物件中包含嵌套物件時,同樣需要保持不變性,逐層展開。

import React, { useState } from 'react';

function NestedObjectUpdateExample() {
const [profile, setProfile] = useState({
name: "Alice",
contact: {
phone: "123-456-7890",
address: "123 Main St",
},
});

// 更新聯絡資訊中的電話
const updatePhone = () => {
setProfile(prevProfile => ({
...prevProfile,
contact: {
...prevProfile.contact,
phone: "987-654-3210"
},
}));
};

return (
<div>
<p>Name: {profile.name}</p>
<p>Phone: {profile.contact.phone}</p>
<p>Address: {profile.contact.address}</p>
<button onClick={updatePhone}>Update Phone</button>
</div>
);
}

export default NestedObjectUpdateExample;
  • 對於嵌套物件 contact,先展開 prevProfile,然後針對 contact 屬性再次使用展開運算子,覆蓋 phone 屬性。

同時更新物件中的多個屬性

import React, { useState } from 'react';

function MultipleUpdateExample() {
const [settings, setSettings] = useState({
theme: "light",
language: "en",
notifications: true,
});

const updateSettings = () => {
setSettings(prevSettings => ({
...prevSettings,
theme: "dark",
language: "zh",
}));
};

return (
<div>
<p>Theme: {settings.theme}</p>
<p>Language: {settings.language}</p>
<p>Notifications: {settings.notifications ? "On" : "Off"}</p>
<button onClick={updateSettings}>Update Settings</button>
</div>
);
}

export default MultipleUpdateExample;
  • 同時更新多個屬性時,使用單一 setSettings 呼叫,將新值與原有值合併。

添加新的物件屬性

import React, { useState } from 'react';

function AddNewPropExample() {
// 初始狀態只有 name 和 age
const [user, setUser] = useState({
name: 'Alice',
age: 30,
});

// 點擊按鈕時,添加新的屬性 address
const addNewProperty = () => {
setUser(prevUser => ({
...prevUser, // 複製原有屬性
address: '123 Main Street', // 添加新的 address 屬性
}));
};

return (
<div>
<h2>User Information</h2>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
<p>Address: {user.address ? user.address : 'Not provided'}</p>
<button onClick={addNewProperty}>Add Address</button>
</div>
);
}

export default AddNewPropExample;
  • 使用展開運算子 (...prevUser) 複製現有的 user 物件,然後再添加新的屬性 address
  • 條件渲染
    在畫面上,使用三元運算子判斷 user.address 是否存在,若存在則顯示地址,否則顯示「Not provided」。

更新陣列中某個項目的值

假設陣列中每個項目都是一個物件,我們需要更新特定項目的屬性。

import React, { useState } from 'react';

function ArrayUpdateExample() {
const [products, setProducts] = useState([
{ id: 1, name: "Laptop", price: 1000 },
{ id: 2, name: "Phone", price: 500 },
]);

// 更新特定產品的價格
const updatePrice = (id, newPrice) => {
setProducts(prevProducts =>
prevProducts.map(product =>
product.id === id ? { ...product, price: newPrice } : product
)
);
};

return (
<div>
{products.map(product => (
<div key={product.id} style={{ marginBottom: "10px" }}>
<span>
{product.name} - ${product.price}
</span>
<button onClick={() => updatePrice(product.id, product.price + 100)}>
Increase Price
</button>
</div>
))}
</div>
);
}

export default ArrayUpdateExample;

使用 map() 方法遍歷陣列,對符合條件的項目使用展開運算子複製原有屬性,再覆蓋掉指定屬性(此處為 price)。

留言
avatar-img
留言分享你的想法!
avatar-img
電資鼠 - 您的學習好夥伴
16會員
242內容數
在當今數位時代,電資領域人才需求爆發式成長,不論是前端網頁設計、嵌入式開發、人工智慧、物聯網還是軟硬體整合,這些技術都在改變世界。而掌握 C/C++、Python、數位邏輯、電路學與嵌入式開發等大學電資領域的課程,正是進入這個高薪、高需求產業的關鍵!
2025/03/06
在 React 中,狀態管理是構建複雜應用的重要一環,其中 useContext 與 Redux 都提供了解決方案,但它們各有優缺點和適用場景。 有鑑於Redux以英文教學為主,網上中文的教學不多,初學者會遇到一些困難,所以本章節希望以一篇文章帶領你快速入門Redux,透過實作的方式上手這個技能!
2025/03/06
在 React 中,狀態管理是構建複雜應用的重要一環,其中 useContext 與 Redux 都提供了解決方案,但它們各有優缺點和適用場景。 有鑑於Redux以英文教學為主,網上中文的教學不多,初學者會遇到一些困難,所以本章節希望以一篇文章帶領你快速入門Redux,透過實作的方式上手這個技能!
2025/03/05
在 React 中,useContext() 是一個 Hook,用來讓你在函式元件中輕鬆地存取 context 資料,避免繁瑣的 props 傳遞。以下是一步步的教學與示例程式碼。 透過本章學習,你將掌握 如何在 React 應用中運用 useContext() 管理全域狀態,提升開發效率!
2025/03/05
在 React 中,useContext() 是一個 Hook,用來讓你在函式元件中輕鬆地存取 context 資料,避免繁瑣的 props 傳遞。以下是一步步的教學與示例程式碼。 透過本章學習,你將掌握 如何在 React 應用中運用 useContext() 管理全域狀態,提升開發效率!
2025/03/05
在本章,我們將使用 React Hooks(useState、useEffect、useRef)來 開發一個碼錶 (Stopwatch) 應用。
2025/03/05
在本章,我們將使用 React Hooks(useState、useEffect、useRef)來 開發一個碼錶 (Stopwatch) 應用。
看更多
你可能也想看
Thumbnail
想在蝦皮雙11買到最划算?這篇文章將分享作者精選的蝦皮高CP值商品,包含HERAN禾聯冷氣、HITACHI日立冰箱、DJI無線麥克風、FUJIFILM拍立得,並提供蝦皮雙11優惠券領取教學、省錢技巧,以及蝦皮分潤計畫介紹,讓你買得開心、省得多!
Thumbnail
想在蝦皮雙11買到最划算?這篇文章將分享作者精選的蝦皮高CP值商品,包含HERAN禾聯冷氣、HITACHI日立冰箱、DJI無線麥克風、FUJIFILM拍立得,並提供蝦皮雙11優惠券領取教學、省錢技巧,以及蝦皮分潤計畫介紹,讓你買得開心、省得多!
Thumbnail
2025 蝦皮 1111 購物節又來了!分享三大必買原因:全站 $0 起免運、多重優惠疊加、便利取貨。 此外,推薦兩款高 CP 值的即食拉麵(無印良品即食迷你拉麵、維力迷你麵野菜拉麵),並分享如何透過「蝦皮分潤計畫」放大效益,開心購物之餘還能獲得額外收益!
Thumbnail
2025 蝦皮 1111 購物節又來了!分享三大必買原因:全站 $0 起免運、多重優惠疊加、便利取貨。 此外,推薦兩款高 CP 值的即食拉麵(無印良品即食迷你拉麵、維力迷你麵野菜拉麵),並分享如何透過「蝦皮分潤計畫」放大效益,開心購物之餘還能獲得額外收益!
Thumbnail
在本章節,我們將學習如何使用 React useState 來管理 陣列 (Arrays) 和物件 (Objects) 的狀態,這是開發 動態應用 時的重要技術。內涵大量必須知道的應用範例,幫助讀者學習。
Thumbnail
在本章節,我們將學習如何使用 React useState 來管理 陣列 (Arrays) 和物件 (Objects) 的狀態,這是開發 動態應用 時的重要技術。內涵大量必須知道的應用範例,幫助讀者學習。
Thumbnail
這篇內容,將會講解什麼是陣列,以及與陣列相關的知識。包括陣列的簡介、陣列的資料限制、陣列的維度、一維陣列、二維陣列。
Thumbnail
這篇內容,將會講解什麼是陣列,以及與陣列相關的知識。包括陣列的簡介、陣列的資料限制、陣列的維度、一維陣列、二維陣列。
Thumbnail
一般在使用 TypeScript 的時候,大家都有遇過定義列舉資料的情境吧。 不過不管是 enum 和 literal 的方式其實都有些小缺點,以下推薦一個個人認為體驗更好的方式。
Thumbnail
一般在使用 TypeScript 的時候,大家都有遇過定義列舉資料的情境吧。 不過不管是 enum 和 literal 的方式其實都有些小缺點,以下推薦一個個人認為體驗更好的方式。
Thumbnail
CSS 是控制網頁外觀的語言,應用於網頁設計、UI/UX 設計、電子商務和移動應用開發。主要使用者包括前端開發者、UI/UX 設計師和網頁設計師。CSS 的特性有樣式控制、層疊優先級、響應式設計及分離內容與樣式。
Thumbnail
CSS 是控制網頁外觀的語言,應用於網頁設計、UI/UX 設計、電子商務和移動應用開發。主要使用者包括前端開發者、UI/UX 設計師和網頁設計師。CSS 的特性有樣式控制、層疊優先級、響應式設計及分離內容與樣式。
Thumbnail
本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。
Thumbnail
本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News