基本介紹
在 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;
- 使用展開運算子
[...]產生新陣列,確保不改變原有陣列。 - 每次點擊按鈕,將新的項目加到陣列末端。

移除陣列中的項目
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方法產生一個不包含指定索引的新陣列,並重新渲染。
現在你可以移除項目清單:
效果:

更新物件
更新物件的單一屬性
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)。













