在 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;
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
)。