Учим useState за 10 минут

Учим useState за 10 минут

25

Доброго времени суток, друзья. На дворе 2К20 год и начиная с версии React 16.8 для работы с состояниями в функциональных компонентах появились хуки. В этой статье мы подробно разберем один из хуков — useState.

Для чего вообще предназначен useState? Если вы работаете с React, то должны были сталкиваться с понятием состояния. Раньше, с состоянием в React можно было работать только в класс компонентах, используя метод setState, которой мы получали наследуя рабочий класс от класса React.Component. Долгое время компоненты функции использовались в качестве ‘глупых’ компонентов, не имеющих состояния, и были предназначены только для рендеринга элементов ui. С версии React 16.8 данный функционал был доработан, теперь при работе с состояниями в функциональных компонентах можно использовать хуки.

Правила хуков

Сперва мы рассмотрим основные правила применения хуков и их особенности:

1. Используйте хуки только на верхнем уровне. Запрещено вызывать хук в методе или цикле. Следуя этому правилу, можно гарантировать правильность выполнения неизменной последовательности при рендере компонента.

2. React полагается на порядок вызова хуков, что позволяет использовать хуки useState, useEffect в одном компоненте многократно.

Пример:


function Example() {

  const [name, setName] = useState('Name')
  const [surname, setSurname] = useState('Surname')
      
    return (
        <div>
            Example
        </div>
}

3. Не применяйте условия, вызывая хуки, поскольку текущая последовательность вызовов в компоненте может быть нарушена. Допустимо использовать выражение внутри хука.

Пример:


function Example() {

        // ошибка
	if(true) {
		useState()
	}
       
    useState()
    useState()
    
    return (
        <div>
            Example
        </div>
    )
}

Практика использования useState

Давайте на примере подробно разберём работу с useState. Для начала работы следует импортировать метод из React.

Пример:


import React, {useState} from 'react'

Далее вызовем его в функции (соблюдая все правила, которые мы рассмотрели выше).

Пример:


import React, {useState} from 'react'

function Count() {

   const [count, setCount] = useState(1)

    return (
        <div>
	    Count
        </div>
    )
}

Хук useState() принимает один параметр в виде начального состояния, которое может быть представлено как значение (строка, число, массив, объект и т.д.) или функция. После вызова функции, useState возвращает массив из двух элементов. Первым элементом является начальное состояние, которое мы передаём,  вторым — функция, изменяющая это состояние при ее вызове и передаче нового значения. Существует несколько способов получения элементов массива:

1. Через индекс

Пример: 


import React, {useState} from 'react'

function Count() {

     const arr = useState(1)

     const increment = () => {
         arr[1](arr[0]+ 1)
     }

    return (
        <div>
	      <button onClick={increment}>+</button>
              <span>
		  {arr[0]}
	     </span>
        </div>
    )
}

2. Через современный синтаксис деструктуризации  ES6 

Пример: 


import React, {useState} from 'react'

function Count() {

    const [count, setCount] = useState(1)

    const increment = () => {
      setCount(count + 1)
    }

    return (
       <div>
	    <button onClick={increment}>+</button>
            <span>
		{count}
	    </span>
       </div>
    )
}

Второй способ более удобный и понятный и его следует использовать в работе как основной. 

Разберем подробнее, что происходит в функции Count. Мы вызвали хук useState, в параметр которого передали значение 1. Это значение будет является начальным состоянием.  Ниже добавлена функция increment, которая будет изменять значение по клику на кнопку и добавлять +1 к текущему состоянию, вызывая setCount(count + 1). Таким образом, каждый клик будет инкрементировать новое значение и счётчик будет увеличиваться.

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


import React, {useState} from 'react'

function Count() {

    const [count, setCount] = useState(1)

    const increment = () => {
	setCount(count + 1)
	setCount(count + 1)
    }

    return (
       <div>
	   <button onClick={increment}>+</button>
           <span>
		{count}
	    </span>
       </div>
    )
}

По клику на кнопку мы обнаружим, что значение увеличивается только на +1, хотя предполагалось, что счетчик покажет +2. Для решения этой задачи в функции изменения setCount можно вызвать функцию в первом аргументе, которой будет возвращено предыдущее состояние count. При каждом новом вызове setCount, значение count будет меняться.

Пример:


import React, {useState} from 'react'

function Count() {

    const [count, setCount] = useState(1)
    const increment = () => {
          setCount(prevCount =>  prevCount + 1)
          setCount(prevCount =>  prevCount + 1)
    }
 
    return (
       <div>
	    <button onClick={increment}>+</button>
           <span>
		 {count}
	    </span>
       </div>
    )
}

Теперь каждый раз по клику, мы получим нужный результат +2.

Работа с объектами

Часто требуется использовать большое количество состояний в одном компоненте. Рассмотрим кейс с формой, содержащей несколько полей.

Пример:


import React, {useState} from 'react'

function LoginForm() {
  const [name, setName] = useState('');
  const [password, setPassword] = useState('');

  const submit = (e) => {
    e.preventDefault();
    console.log(name, password);
  };

  return (
    <form onSubmit={submit}>
      <label>
        Имя:
        <input
          value={name}
          onChange={event => setName(event.target.value)}
          name="name"
          type="text"
        />
      </label>
        <label>
        Пароль:
        <input
          value={password}
          onChange={event => setPassword(event.target.value)}
          name="password"
          type="password"
        />
      </label>
          <button>Отправить</button>
    </form>
  );
}

Чтобы не писать useState множество раз, можно использовать объект (или массив) для хранения всего состояния целиком. На примере объекта, посмотрим как можно работать с формой.

Пример: 


function LoginForm() {

  const [form, setForm] = useState({
    name: '',
    password: ''
  });

  const submit = e => {
    e.preventDefault();
    console.log(form.username, form.password);
  };

  const update = e => {
    setState({
      ...form,
      [e.target.name]: e.target.value
    });
  };

  return (
    <form onSubmit={submit}>

      <label>
     	Имя:
        <input
          value={form.name}
          name="name"
          onChange={update}
        />
      </label>
      
    <label>
        Пароль:
        <input
          value={form.password}
          name="password"
          type="password"
          onChange={update}
        />
      </label>

      <button>Отправить</button>
    </form>
  );
}

В useState помещаем начальное состояние формы. При отправлении формы вызываем метод submit, в котором увидем текущее состояние. Для изменения состояний input’ов используется метод update, в котором через атрибут name и value из e.target получаем данные и при изменении отправляем их как новое состояние формы через setState. Чтобы каждый раз не ‘перетирать’ предыдущее состояние другого input’a, используется спред оператор (…), позволяющий копировать предыдущее состояние.

Заключение

Сегодня мы рассмотрели особенности работы с хуком useState, а также общие правила использования хуков. На примерах разобрали некоторые рабочие кейсы (состояния, объекты, работа с формой).  Надеюсь, что данная статья была вам полезна. Учитесь, думайте, пишите код. Удачного кодинга, друзья!

Полезные материалы:

https://ru.reactjs.org/docs/hooks-intro.html — официальная документация по React Hooks

Подписывайтесь на наш канал в Telegram для получения самой последней и актуальной информации. 

1+
JavaScript ES2020

Что нового в JavaScript ES2020 (ES11) ?

150

Доброго времени суток, друзья. На дворе 2К20 год. Окунемся в текущие новшества JavaScript. В этой статье мы рассмотрим следующие темы:

— BigInt

 — Dynamic import

 — GlobalThis

 — Private Class Variables

 — Promise.allSettled()

 — Nullish Coalescing Operator

 — Optional Chaining Operator

 — Numeric Separators

 — String.protype.matchAll

 — import.meta

 — export * as nameModule from «module»

Теперь мы разберем каждую из них более подробно.

Читать далее «Что нового в JavaScript ES2020 (ES11) ?»

2+

Декораторы в React или как оптимизировать ваши компоненты.

7 591

Доброго времени суток друзья. Как часто вы создаете компоненты и вам приходится повторять одинаковый функционал? На практике, если вам нужно создать кнопку которая будет что-то открывать и в следующем компоненте опять же будет кнопка которая будет что-то открывать,  стоит задуматься о декораторах.

Декораторы в React это отличный способ оптимизации вашего приложения путем сокращения дублирующих элементов. На практике это функция которая будет принимать на входе текущий компонент и просто оборачивать его с верху компонентом оберткой с состоянием и возможными событиями. Читать далее «Декораторы в React или как оптимизировать ваши компоненты.»

1+

Как работает bind? Пишем полифилл для bind

6 781

Доброго времени суток друзья. Сегодня я хотел бы поговорить с вами о bind. Для чего он вообще используется и как с ним работать? Общее определение: «Метод bind() создаёт новую «привязанную функцию» (ПФ).  ПФ — это «необычный функциональный объект» ( термин из ECMAScript 6 ), который является оберткой над исходным функциональным объектом. Вызов ПФ   приводит к исполнению кода обернутой функции.” Взято тут. В практики bind используется для создания функции с предопределенными аргументами. А так же он полезен в случаях, если вы хотите создать сокращение для функции, требующей определенное значение this. Читать далее «Как работает bind? Пишем полифилл для bind»

1+

Курс для Junior разработчика. Основы JavaScript. Синтаксис. Часть 2.

1 311

Доброго времени суток друзья. Вот и пришло время вновь продолжить наш курс по JavaScript. Хочу обратить ваше внимание что статьи по циклу основы JavaScript предназначены для тех кто еще только начинает свой путь в веб программирование и некоторые моменты я стараюсь по максимуму упростить для процесса обучения. Вы готовы? Если да то эта статья для вас.
Читать далее «Курс для Junior разработчика. Основы JavaScript. Синтаксис. Часть 2.»

2+
Web Game Developer Знакомство с Phaser

Game Developer и WEB. Знакомство с Phaser

1 808

Доброго времени суток! Прежде чем читать данную статью позволь мне задать тебе несколько вопросов. Нравится ли тебе игры? Играешь ли ты в них? Мечтал ли ты когда нибудь написать свою собственную игру? Уже несколько лет я переодически пишу игры ( в основном на JS ). Игры для мобильных приложений, игры для браузеров, десктопные игры. Я не являюсь профессиональным разработчика игр, данное занятие это мое хобби в не рабочее время. Читать далее «Game Developer и WEB. Знакомство с Phaser»

0
Оптимизация React приложений

Оптимизация React приложений

1 884

Всем доброго времени суто друзья. Если вы занимаетесь разработкой приложений на React то рано или поздно вы столкнетесь с проблемой медленной работы приложения из-за разрастания общей архитектуры и ее функционала. Если перед вами стала задача оптимизировать приложение то эта статья специально для вас. Читать далее «Оптимизация React приложений»

0
react

ТОП плагинов для написания React приложений на Atom

2 726

В сегодняшней статье я постараюсь дать максимум полезной информации на тему плагинов для вашего Atom редактора если вы «пилите» React приложения. Есть отличное решение в виде набора плагинов для Atom если вы решили расширить функционал редактора. Вот ссылка atom-react. Если открыть консоль в самом редакторе и ввести apm install react то будут инсталлирован целый набор полезных плагинов которые облегчат жизнь начинающему React разработчику. Читать далее «ТОП плагинов для написания React приложений на Atom»

3+
Клонирование объектов или иммутабельнсть данных

Клонирование объектов или иммутабельнсть данных

889

Доброго времени суток! При разработки проектов со сложной структурой данных частенько возникают проблемы, когда в результате работы данные начинают неожиданно меняться, что приводит к большому числу багов и «задебажить» это бывает очень тяжело. Что бы решить эту проблему можно пойти несколькими путями:

1. Склонировать сложный объект и продолжить с ним работу

2. Создать «иммутабельность» данных Читать далее «Клонирование объектов или иммутабельнсть данных»

0
ТОП ReactJS библиотек компонентов

ТОП ReactJS библиотек компонентов

3 191

Доброго времени суток! Когда вы уже давольно не плохо начинаете понимать ReactJS то в место того что бы «пилить» компоненты самостоятельно вы обращаетесь к готовым решениям, что является естественной практикой в современном программирование ( дабы не создавать свое колесо ). Сегодня я хочу представить вам топ ReactJS библиотек, фремворков UI компонентов, которые ( по моем автора ) являются самыми лучшими решения на сегодняшний момент. Поехали. Читать далее «ТОП ReactJS библиотек компонентов»

0