Как хранить и обновлять объекты в хуке useState в React

В предыдущей статье я рассказал, как хранить и обновлять массивы в useState hook. В этой статье мы рассмотрим, как изменять хранимые объекты с помощью useState hook.

Настройка проекта

Создайте проект react с помощью следующей команды:

npx create-react-app react-usestate-object
Войти в полноэкранный режим Выйти из полноэкранного режима

Обновление объекта state

Создадим 2 поля с firstName и lastName:

import { useState } from "react"

function App() {
  const [name, setName] = useState({ firstName: "", lastName: "" })

  return (
    <div className="App">
      <div>
        <label htmlFor="firstName">First Name: </label>
        <input
          type="text"
          name="firstName"
          id="firstName"
          value={name.firstName}
        />
      </div>
      <div>
        <label htmlFor="lastName">Last Name: </label>
        <input
          type="text"
          name="lastName"
          id="lastName"
          value={name.lastName}
        />
      </div>
      <div>
        Name is: {name.firstName} {name.lastName}
      </div>
    </div>
  )
}

export default App
Вход в полноэкранный режим Выход из полноэкранного режима

Здесь у нас есть объект name в качестве локального состояния для хранения firstName и lastName. В настоящее время эти поля доступны только для чтения.

Давайте добавим функции onChange к этим полям и будем обновлять объект state, когда пользователи вводят текст в поле ввода:

import { useState } from "react"

function App() {
  const [name, setName] = useState({ firstName: "", lastName: "" })

  const setFirstName = e => {
    setName(existingValues => ({
      // Retain the existing values
      ...existingValues,
      // update the firstName
      firstName: e.target.value,
    }))
  }

  const setLastName = e => {
    setName(existingValues => ({
      // Retain the existing values
      ...existingValues,
      // update the lastName
      lastName: e.target.value,
    }))
  }

  return (
    <div className="App">
      <div>
        <label htmlFor="firstName">First Name: </label>
        <input
          type="text"
          name="firstName"
          id="firstName"
          value={name.firstName}
          onChange={setFirstName}
        />
      </div>
      <div>
        <label htmlFor="lastName">Last Name: </label>
        <input
          type="text"
          name="lastName"
          id="lastName"
          value={name.lastName}
          onChange={setLastName}
        />
      </div>
      <div>
        Name is: {name.firstName} {name.lastName}
      </div>
    </div>
  )
}

export default App
Вход в полноэкранный режим Выход из полноэкранного режима

Здесь мы используем оператор spread, чтобы сохранить существующие значения и обновить только необходимые.

Объединение обновления в одну функцию

Поскольку функциональность обновления обоих полей одинакова, мы можем написать общую функцию обновления, как показано ниже:

import { useState } from "react"

function App() {
  const [name, setName] = useState({ firstName: "", lastName: "" })

  const updateName = e => {
    const fieldName = e.target.name
    setName(existingValues => ({
      // Retain the existing values
      ...existingValues,
      // update the current field
      [fieldName]: e.target.value,
    }))
  }

  return (
    <div className="App">
      <div>
        <label htmlFor="firstName">First Name: </label>
        <input
          type="text"
          name="firstName"
          id="firstName"
          value={name.firstName}
          onChange={updateName}
        />
      </div>
      <div>
        <label htmlFor="lastName">Last Name: </label>
        <input
          type="text"
          name="lastName"
          id="lastName"
          value={name.lastName}
          onChange={updateName}
        />
      </div>
      <div>
        Name is: {name.firstName} {name.lastName}
      </div>
    </div>
  )
}

export default App
Войти в полноэкранный режим Выйти из полноэкранного режима

Здесь мы использовали нотацию [variableContainingPropertyName] для установки значения соответствующего объекта.

Если полей много, можно воспользоваться хуком useReducer,
что также помогает при валидации формы.

Оцените статью
devanswers.ru
Добавить комментарий