在 React 中更新状态数组

Irakli Tchigladze 2023年1月30日
  1. React 中的状态是什么
  2. 在 React 中使用 setState() 方法
  3. 在 React 中更新数组状态值
  4. 在 React 中克隆数组或添加元素的其他方法
在 React 中更新状态数组

本文想探讨 state 对象以及限制直接改变状态的根本原因。

React 中的状态是什么

React 是一个库,可让你自由地开发和设计可重用组件的样式。与 WordPress 等常见 CMS 网站或 SquareSpace 等网站构建软件相比,使用 React 构建的 Web 应用程序更快、更可定制。

React 不是一个固执己见的库,它背后的团队让 React 开发人员可以自由地按照自己的方式做事。尽管如此,该库仍然建立在某些原则之上,例如 props 的不变性和更新状态的必要程序。

一些 React 组件维护它们的状态来存储预期由于用户操作、加载的数据或其他事件而改变的数据。它是一个对象,用户可以将他们的键值对分配给这个对象。

state 最重要的特性之一是 state 值的更改会自动触发重新渲染。如果你使用可变值来呈现你的应用程序,那么 state 是存储它的理想场所。

如果你需要一个变量在 render 方法之外进行计算,你可以定义一个简单的变量或在组件实例上设置一个属性。

组件的 stateprops 之间的最大区别在于,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 变量。

Irakli Tchigladze avatar Irakli Tchigladze avatar

Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.

LinkedIn

相关文章 - React State