Как применять хуки React в проекте React

В этой статье вы познакомитесь с React Hooks, новой функцией версии React 16.8. React Hooks, или хуки — это функции, которые служат модульной заменой методов состояния и жизненного цикла. Вместо компонентов класса хуки React позволяют создавать функциональные компоненты.

Требования

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

Анализ метода useState()

В компоненте класса было необходимо импортировать React в файл index.js и создать экземпляр объекта класса JustAnotherCounter. Ранее вы должны были бы добавить состояние и функцию для обновления счетчика count:

import React, { Component } from 'react';

class ScoreCounter extends Component {
  state = {
    count: 0
  };

  setCount = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <h1>{this.state.count}</h1>

        <button onClick={this.setCount}>Count Up To The Moon</button>
      </div>
    );
  }
}

В методе жизненного цикла render нужно было вернуть значение, хранящееся в состоянии, и кнопку, которая вызывает функцию при каждом нажатии.

Давайте теперь рассмотрим компонент класса ScoreCounter как функциональный компонент.

С помощью хуков React вы можете сжать состояние и методы жизненного цикла в функциональный компонент в файле index.js – получится компонент с меньшим количеством строк. Импортируйте useState в деструктурированный объект:

import React, { useState } from 'react';

function ScoreCounter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>Count Up To The Moon</button>
    </div>
  );
}

Метод useState() деструктурирует объект состояния в массив и присваивает его элементам значение вызова хука. Первый элемент — это состояние, а второй — функция, работающая как метод .setState(). Аргумент, который вы передаете в метод useState(), работает как начальное значение состояния, а число 0 является счетчиком. В качестве начального значения состояния вы можете передать любой тип данных, например массивы, объекты, строки и числа.

С каждым нажатием кнопки функция setCount() передает состояние в качестве аргумента, который увеличивается на 1.

Теперь у вас есть функциональный компонент ScoreCounter, который требует меньше синтаксиса и работает на удобочитаемость кода.

Вы также можете использовать метод useState() несколько раз в одной и той же функции. В файл index.js импортируйте useState и объявите функциональный компонент Login:

import React, { useState } from 'react';

function Login() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');

  return (
    <div className="login">
      <form>
        <label>
            Username: <input value={username} onChange={event => setUsername(event.target.value)}/>
            <br />
            Password: <input value={password} onChange={event => setPassword(event.target.value)}/>
          </label>
        <button>Submit</button>
      </form>
    </div>
  );
}

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

Разобравшись с useState(), давайте взглянем на другие методы хуков React.

Использование метода useEffect()

Хуки React представляют метод useEffect() для замены методов жизненного цикла компонента класса componentDidMount, componentDidUpdate и componentWillUnmount. Этот метод также поддерживает побочные эффекты в функциональном компоненте (такие как изменение содержимого в объектной модели документа и выборка данных). useEffect() будет запускаться после рендеринга каждого компонента.

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

В файле index.js импортируйте useEffect в компонент ScoreCounter:

[label index.js]

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

function ScoreCounter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(count);
    document.title = `Your new score is ${count}`;
  });

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>Count Up To The Moon</button>
    </div>
  );
}

Здесь useEffect() создает побочные эффекты входа в консоль для проверки значения начального состояния в count и обновления объектной модели документа.

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

В файле index.js используйте пустой массив в качестве второго аргумента к методу useEffect():

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

function ScoreCounter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(count);
    document.title = `Your new score is ${count}`;
  }, []);
}

При рендеринге ScoreCounter метод useEffect() будет сохранять каждый экземпляр count в массиве и обновлять компонент, если значение отличается от предыдущего вызова. Выходит, useEffect() объединяет функциональные возможности методов жизненного цикла componentDidMount и componentDidUpdate в одном вызове.

Чтобы имитировать метод жизненного цикла componentWillUnmount, верните функцию в методе useEffect() в файле index.js:

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

function ScoreCounter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(count);
    document.title = `Your new score is ${count}`;

    return () => console.log(`Component is unmounted`);
  }, []);
}

Объявляя и возвращая анонимную функцию, метод useEffect() размонтирует компонент за один вызов (здесь это делается с помощью console.log для проверки его состояния).

Передайте fetch в useEffect(), чтобы получить информацию из внешнего API.

В файле index.js импортируйте useState и useEffect. Объявите функциональный компонент GitHubUsers и передайте выборку в теле useEffect:

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

function GitHubUsers() {
  const [user, setUsers] = useState([]);

  useEffect(() => {
    fetch('https://api.github.com/users')
      .then(response => response.json())
      .then(data => {
        setUsers(data); // set users in state
      });
  }, []);

Обратите внимание, что второй аргумент задан как пустой массив. Это нужно для того, чтобы сообщить useEffect() о том, что его нужно выполнить один раз. Метод useEffect() вызовет fetch для вызова GitHub API и установит ответ в объект JSON.

После успешного вызова включите оператор return в компонент GitHubUsers, чтобы выполнить итерацию по данным и вывести информацию о пользователе GitHub:

  return (
    <div className="section">
      {users.map(user => (
        <div key={user.id} className="card">
          <h5>{user.login}</h5>
        </div>
      ))}
    </div>
  );
}

Метод useEffect() использует функциональность всех трех методов жизненного цикла компонента класса в одном вызове (он выполняет вход в консоль, обновляет объектную модель документа и получает данные из внешнего API).

Заключение

Методы useState() и useEffect() — мощные дополнения к библиотеке React. Теперь с помощью React Hooks вы можете усилить свои функциональные компоненты с помощью методов состояния и жизненного цикла, при этом используя меньше кода.

Читайте также: Как работать с Context API в React и React Hooks

Tags:

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