Управление состоянием формы с помощью хука React useState 🪝.

Примерное время чтения: 8 минут


Если вы начинаете работать с React, то вам предстоит узнать о State. Если вы еще не совсем знакомы с state, мы можем кратко описать state как переменную, которая хранит данные/информацию в вашем компоненте React, эти данные могут обновляться/изменяться по мере того, как пользователи взаимодействуют с вашим приложением.

Чтобы помочь нам управлять состоянием в нашем компоненте, React предоставляет нам State Hook, который мы можем использовать для хранения и установки этих данных.

Мы будем работать над кодом для простой формы с двумя входами, именем и фамилией.

Давайте посмотрим пример, чтобы попытаться освоиться. Взгляните на этот код здесь, а ниже я постараюсь объяснить.

//React Code

export default function Form() {
    const [firstName, setFirstName] = React.useState("")
    const [lastName, setLastName] = React.useState("")

    function handleFirstNameChange(event) {
        setFirstName(event.target.value)
    }

    function handleLastNameChange(event) {
        setLastName(event.target.value)
    }

    return (
        <form>
            <input
                type="text"
                placeholder="First Name"
                onChange={handleFirstNameChange}
            />
            <input
                type="text"
                placeholder="Last Name"
                onChange={handleLastNameChange}
            />
        </form>
    )
}
Вход в полноэкранный режим Выход из полноэкранного режима

В верхней части кода React вы увидите, что мы используем хук useState() два раза.

Один раз для изменения состояния ввода имени и другой — для фамилии. Мы храним наше состояние (данные) для первого имени в переменной firstName, а затем используем функцию setFirstName для обновления того, что в ней хранится.

Когда мы инициализируем состояние для переменных firstName и lastName, вы увидите, что мы инициализируем состояние равным значению пустой строки с помощью useState(«»).

Чуть ниже вы увидите две другие функции, handleFirstNameChange и handleLastNameChange. Каждый элемент <input/>, расположенный ниже, имеет свойство onChange, которое слушает изменения в этом конкретном элементе и выполняет функцию, содержащуюся в качестве его значения.

Короче говоря, функция, которая будет выполняться при любых изменениях в нашем вводе первого имени, — это handleFirstNameChange. Для ввода фамилии есть своя функция handleLastNameChange.

Этот код работает очень хорошо 😊! При обновлении ввода первого имени будет выполняться соответствующая функция; самое интересное, что при срабатывании функции onChange она автоматически передает объект события в нашу функцию-обработчик. Если вы посмотрите на каждый обработчик изменений, то увидите, что они принимают параметр события.

Мы можем разбить это событие на части, чтобы увидеть изменения, посмотрев на event.target.value (строка 8, где мы регистрируем обновленное значение), вот как это выглядит ниже.

Хотя это работает, такое решение не масштабируется. Представьте, что у вас есть форма с 10+ входами. Не очень практично писать функцию handleChange для каждого входа на странице.

В программировании мы стараемся сохранить наш код настолько DRY 🌵 (Don’t Repeat Yourself), насколько это возможно. Итак, давайте исправим это, чтобы убедиться, что мы не дублируем уже написанный код.

Посмотрите на исправленный код ниже!

export default function Form() {
    const [formData, setFormData] = React.useState(
        {firstName: "", lastName: ""})

    function handleChange(event) {
        setFormData(prevState => {
            return{
                ...prevState,
                [event.target.name]: event.target.value
            }
        })
    }
    console.log(formData)
    return (
        <form>
            <input
                type="text"
                placeholder="First Name"
                onChange={handleChange}
                name="firstName"
            />
            <input
                type="text"
                placeholder="Last Name"
                onChange={handleChange}
                name="lastName"
            />
        </form>
    )
}

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

Давайте обратим внимание на несколько основных отличий.

  1. Теперь есть только одна функция handleChange. Мы избавились от handleLastnameChange и handleFirstNameChange.

  2. Мы добавили свойство name к нашим входам. Один вход имеет значение имени firstName, а другой — lastName. Запомните это для вишенки на вершине 🍒!

3.) Наше начальное состояние вверху называется по-другому, так же как и функция изменения состояния. (Они переименованы, чтобы мы знали, что они более «общие». Названия не имеют никакого отношения к их поведению)

4.) Наша функция handleChange выглядит немного иначе (см. ниже).

    function handleChange(event) {
        setFormData(prevState => {
            return{
                ...prevState,
                [event.target.name]: event.target.value
            }
        })
    }
Вход в полноэкранный режим Выйти из полноэкранного режима

Таким образом, мы можем обрабатывать изменения для обоих входов с помощью одной функции. Мы вызываем setFormData (нашу новую функцию состояния). Хук useState дает нам доступ к предыдущему состоянию, которое мы можем использовать для обновления текущего состояния новым!

Если мы console.log() prevState сейчас (синяя стрелка), вы увидите, что она регистрирует последнее значение состояния, в данном случае это инициализированное состояние, которое мы сохранили в formData (зеленая).

Круто, да?

Теперь последняя часть — это вишенка на вершине 🍒. Функция handleChange собирается вернуть обновленное состояние (тип объекта).

Вот ее оператор возврата:

            return{
                ...prevState,
                [event.target.name]: event.target.value
            }
Вход в полноэкранный режим Выйти из полноэкранного режима

Мы используем оператор распространения (это 3 точки), чтобы сделать копию нашего объекта prevState, а затем, после запятой, мы обновляем [event.target.name]. Помните свойство name, которое мы добавили к нашим входам? Это говорит handleChange вернуть предыдущее состояние, но обновить это конкретное свойство name, чтобы оно было равно значению цели (элемента ввода), который получил событие.

Таким образом, он говорит: если вход с name=»firstName» является целевым, давайте возьмем предыдущее состояние этого компонента и обновим ключ (name) новым значением.

Вот и все! Не такой уж короткий, но, безусловно, мощный инструмент, который React дает нам, чтобы сохранить наш код чистым и более удобным для обслуживания.

Если у вас есть какие-либо другие замечания, пожалуйста, не стесняйтесь поделиться ими! Я всегда рад узнать больше о том, как улучшить свою работу 🤘🏾.

Вот щенок

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