HOWTO · React
在 React 中更新狀態陣列
在本文中,我們將探索狀態,這是 React 的一個組成部分,因為它允許我們建立動態使用者介面。
本頁內容
本文想探討 state 物件以及限制直接改變狀態的根本原因。
React 中的狀態是什麼
React 是一個庫,可讓你自由地開發和設計可重用元件的樣式。與 WordPress 等常見 CMS 網站或 SquareSpace 等網站構建軟體相比,使用 React 構建的 Web 應用程式更快、更可定製。
React 不是一個固執己見的庫,它背後的團隊讓 React 開發人員可以自由地按照自己的方式做事。儘管如此,該庫仍然建立在某些原則之上,例如 props 的不變性和更新狀態的必要程式。
一些 React 元件維護它們的狀態來儲存預期由於使用者操作、載入的資料或其他事件而改變的資料。它是一個物件,使用者可以將他們的鍵值對分配給這個物件。
state 最重要的特性之一是 state 值的更改會自動觸發重新渲染。如果你使用可變值來呈現你的應用程式,那麼 state 是儲存它的理想場所。
如果你需要一個變數在 render 方法之外進行計算,你可以定義一個簡單的變數或在元件例項上設定一個屬性。
元件的 state 和 props 之間的最大區別在於,state 應該通過設計而改變。
要使 React Virtual DOM 功能正常工作,你必須使用內建方法來更新狀態。你不能使用諸如 .push() 之類的方法來直接改變狀態物件。
在 React 中使用 setState() 方法
React 元件在內部使用 setState() 方法來修改狀態。React 團隊強烈建議只使用 setState() 方法改變狀態而不繞過它。
它有一個引數:一個應該取代現有狀態的物件。React 開發人員通常必須複製現有的狀態物件,對副本進行必要的更改,呼叫 setState() 方法,並將副本作為引數提供。
在 React 中更新陣列狀態值
狀態屬性的值型別沒有限制。它可以是任何東西:字串、數字、物件,甚至是陣列。在 React 中,將陣列作為狀態值是很常見的。
讓我們用一個實際的例子。假設你的狀態值是一個包含多個物件的陣列,每個物件都包含動物資料。
讓我們看看如何在實踐中使用那個 state 值。
import "./styles.css";
import { useState } from "react";
export default function App() {
const [animals, setAnimals] = useState([
{ type: "Lion" },
{ type: "Rabbit" },
{ type: "Wolf" }
]);
return (
<div className="App">
{animals.map((animal) => (
<h1>{animal.type}</h1>
))}
</div>
);
}
到目前為止,一切都很簡單。我們使用 useState() 掛鉤將 animals 狀態變數的預設值設定為陣列。然後我們使用 .map() 方法為每個動物渲染一個 <h1> 元素。
但是,當你需要另一隻動物加入陣列時會發生什麼?例如,讓我們新增一個表單,使用者可以在其中輸入動物的型別。
一旦我們從 input 元素訪問值,我們將不得不以某種方式將該值新增到 animals 狀態變數,這是一個陣列。
export default function App() {
const [animals, setAnimals] = useState([
{ type: "Lion" },
{ type: "Rabbit" },
{ type: "Wolf" }
]);
const handleClick = () => setAnimals([...animals, { type: "Sparrow" }]);
return (
<div className="App">
{animals.map((animal) => (
<h1>{animal.type}</h1>
))}
<button onClick={() => handleClick()}>Update the State</button>
</div>
);
}
如果你嘗試直接執行 animals.push({type:"cat"}),則會導致程式碼出錯。
相反,在這個例子中,我們新增了一個簡單的按鈕,當點選它時,使用擴充套件語法複製原始 animals 狀態陣列的所有值,再新增一個物件,然後更新狀態。你可以在 CodeSandbox 上檢視演示。
複製陣列、修改陣列並使用變異陣列更新狀態變數似乎效率低下。儘管如此,在符合 React 建議的同時,它仍然是最直接的方法。
在 React 中克隆陣列或新增元素的其他方法
在上面的例子中,我們使用擴充套件語法來複制陣列,再新增一個物件並更新狀態。但是,也可以使用 .concat() 方法將特定值新增到陣列中。
const newAnimalsArray = animals.concat([{ type: "Sparrow" }])
然後我們可以呼叫 setAnimals() 更新函式並提供 newAnimalsArray 作為引數。
同樣,我們可以使用 .push() 方法將某些專案新增到陣列的末尾。
或者,我們可以使用 Array 名稱空間上的 .from() 方法來複制陣列。讓我們來看看。
const copiedArray = Array.from(animals)
copiedArray.push({type: "Sparrow"})
setAnimals(copiedArray)
React 中的類元件
類元件是過去唯一可以保持狀態的型別。setState() 是更新類元件中狀態的唯一有效方法。
但是,它比 useState() 鉤子稍微冗長一些。
React 中的函式式元件
自從 React 16.8 版本引入鉤子以來,在功能元件中維護狀態成為可能。這是一個非常流行的特性,並促使 React 開發者社群更頻繁地使用函式式元件。
在功能元件中,我們一起定義了兩個變數。第一個變數指的是狀態值本身,useState() 鉤子返回的第二個值是更新函式。
假設我們有一個 number 狀態變數和另一個 setNumber 函式要更新。
const [number, setNumber] = useState(0)
useState 鉤子負責其餘的工作。它將狀態值分配給 number 變數,將更新函式分配給 setNumber 變數。