Хук useState

useState – это hook, который позволяет создавать локальный стейт в функциональных компонентах. Точнее это не совсем такой локальный стейт, как у классовых компонент. Так как там он действительно локальный, ведь хранится внутри функции в виде объекта, а здесь же данны хранятся где-то “в стороне” – в мире Реакта. Просто они сохраняются при перезагрузки функций особым образом в этой памяти.

Применение

1. Импортируем из реакт, как и другие хуки:

import React, { useState, useEffect } from 'react';

2. useState всегда возвращает массив с двумя элементами. Вот пример, где мы присваиваем этот массив переменной, а потом достаем первый и второй элемент (так не пишут, это пример!):

let stateWithSetState = useState(true); //отдает массив с двумя элементами
let editMode = stateWithSetState[0]; //первый элемент – это само значение
let setEditMode = stateWithSetState[1]; //второй элемент – это функция для изменения

3. Как видно из комментариев в примере, первый элемент массива – это само значение (изначально у нас это “true”), а второй – это функция для изменения первого элемента.

4. Когда применяется перерисовка (вызывается функция из второго элемента массива), то компонента перерисовывается.

На практике пишут вот тактим образом:

let [editMode, setEditMode] = useState(false); //деструктивное присваивание для более короткой записи

5. Концепция применения нескольких объектов в хуках отличается от той, что в классовых компонентах. Здесь нужно дробить стейт на несколько элементов, если объектов встейте больше одного. То есть просто каждый раз прописывать то, что в примере выше. Например, нам в компоненте нужен еще один объект дополнительный в локальном стейте:

let [editMode, setEditMode] = useState(false); 
 let [status, setStatus] = useState(props.status); //при работе с хуками приходится для каждого свойства стейта так делать

Пример фрагмента с проекта с применением useState

import React, { useState } from 'react';
import s from './ProfileInfo.module.css';


const ProfileStatusWithHooks = (props) => {

  let [editMode, setEditMode] = useState(false);
  let [status, setStatus] = useState(props.status);
  
  const activateEditMode = () => {
    setEditMode(true); //изменяем свойство стейта, чтобы появился инпут для изменения статуса пользователя
  }

  const deactivateEditMode = () => {
    setEditMode(false); //изменяем свойство стейта, чтобы инпут исчез
    props.updateStatus(status);
  }

  const onStatusChange = (e) =>{
    setStatus(e.currentTarget.value);
  }

    return  (
          <div>
            { !editMode &&
              <div>
              <span onDoubleClick={activateEditMode}>{props.status || "------"}</span> //при двойном клике запускаем изменение стейта
              </div>
            }
            { editMode &&
              <div>
                  <input onChange={onStatusChange}
                     autoFocus={true} 
                     onBlur={ deactivateEditMode } //при клике мимо фокуса запускаем изменение стейта
                     value={status} />
              </div>
            }
        </div>
      )
}

export default ProfileStatusWithHooks;

Этот пример еще сырой, так как в нем теперь нужно применить другой хук – useEffect, чтобы данные из пропсов действительно попадали сразу внутрь инпута при двойном клике по статусу, а не через раз (компонента не всегда успевает загрузиться до получения данных из сервера, которые приходят через пропсы).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *