Разбираемся с React: компоненты

React – фронтенд-библиотека для создания веб-приложений.

Концепция компонентов – одна из самых важных в React. Компоненты в React просто создавать и переиспользовать, вокруг компонентов строится вся разработка.

Давайте разберемся с ними подробнее.

Что такое React-компоненты?

Компоненты в React – независимые единицы, из которых складывается приложение. Вы можете думать о компонентах, как о строительных блоках, из которых потом собирается дом – React-приложение. При разработке на React вы будете использовать компоненты постоянно – без их создания написать приложение не получится (как не получится построить дом без кирпичей). Иерархически собранные компоненты и представляют собой React-приложение.

const myFirstComponent = () => <h1>Yes! I wrote a component</h1>

Код выше описывает создание очень простого функционального компонента, который показывает заголовок h1. Важно понимать, возвращаемая компонентом разметка – не HTML. Это JSX. Подробнее о том, что такое JSX, можно прочитать здесь.

Типы компонентов

В React есть два типа компонентов:

  1. Классовые компоненты (основанные на классах)
  2. Функциональные компоненты (компоненты, основанные на функциях)

Начнем с разбора классовых компонентов.

Классовые компоненты (stateful – обладают состоянием)

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

import React from "react";

const FunctionComponent = (props) => {
  return (
    <div>
      <form>
        <input placeholder="Enter Term..." />
        <button>Submit</button>
      </form>
      <div>
        <h1>{props.message}</h1>
      </div>
    </div>
  );
};

export default FunctionComponent;

state (состояние)

Состояние React-компонента (state) – объект, в котором находятся данные, которые могут изменяться со временем, т.е. Уже после того, как компонент был отрисован. Состояние – изменяемый (mutable) объект. Вы можете думать о state как о properties, которые могут влиять на поведение UI после первого рендера.

import React, { Component } from "react";

class App extends Component {
  state={firstname:'', lastname:''}

  render(){
    return (
      <div>
      <form>
        <input
          placeholder='firstname'
          value={this.state.firstname}
          onChange={(e)=>{this.setState({firstname:e.target.value})}}
        />
         <input
          placeholder='lasttname'
          value={this.state.lastname}
          onChange={(e)=>{this.setState({lastname:e.target.value})}}
        />
        <button onClick={(e)=>{e.preventDefault()}}>click</button>
      </form>

</div>
    )
  }
}

export default App

В приведенном коде на каждое событие keypress в input-e форм, происходит перерисовка (rerender) компонента и изменяется состояние UI.

Lifecycle-методы

Lifecycle-методы описывают весь жизненный цикл компонента от момента его инициализации до момента уничтожения (например, в результате закрытия страницы или удаления). Вот три главных lifecycle-метода:

  1. componentDidMount
  2. componentDidUpdate
  3. componentWillUnmount

componentDidMount

Этот метод вызывается один раз – сразу после того, как компонент был отрисован. Вы можете использовать этот метод, чтобы загрузить данные, которые нужно показать сразу после отрисовки компонента браузером.

componentDidMount() {
  console.log('Я выполнился, как только отрендерился компонент')
}

Код выше выведет в консоль надпись “Я выполнился, как только отрендерился компонент.” сразу после того, как отрендерится компонент.

componentDidUpdate

componentDidUpdate вызывается, когда происходит изменения состояния уже отрисованного компонента. Метод принимает два аргумента – предыдущие properties и предыдущий state компонента.

componentDidUpdate(prevProps, prevState) {
  if (prevState.colors !== this.state.colors) {
    console.log('colors has changed.')
  }
}

componentDidUpdate вызывается в случае, если предыдущее состояние компонента не равно следующему состоянию.

componentWillUnmount

Метод вызывается, когда компонент удаляется из DOM-дерева. Это последний метод из жизненного цикла компонента. Тут можно разместить код, который должен быть выполнен прямо перед удалением компонента – например, удалить ненужные данные.

componentWillUnmount(){
    console.log('Прямо сейчас произойдет удаление компонента.');
}

Код выше выведет в консоль текст прямо перед удалением компонента.

Функциональные компоненты (stateless)

Функциональные (stateless) компоненты – компоненты без состояния. Это обычная JavaScript функция, возвращающая JSX. Используются для того, чтобы получить props и отрисовать JSX. Функциональный компонент не управляет состоянием (на самом деле, есть способ – мы рассмотрим его ниже), таким образом, не может вызывать собственную перерисовку.

import React from "react";

const FunctionComponent = (props) => {
  return (
    <div>
      <form>
        <input placeholder="Enter Term..." />
        <button>Submit</button>
      </form>
      <div>
        <h1>{props.message}</h1>
      </div>
    </div>
  );
};

export default FunctionComponent;

Код выше создает функциональный компонент, возвращающий JSX с input-элементом и кнопкой Submit и заголовком h1, показывающим сообщение из props. Props в этот компонент будут приходить из компонента верхнего уровня.

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

Хуки позволяют “захватить” состояние в функциональном компоненте – для этого используется useState хук. Lifecycle-методами можно пользоваться с помощью хука useEffect.

useState

useState в функциональном компоненте делает то же, что делает setState в классовом компоненте.

import React from "react";

const FunctionalInput = () => {
  const [state, setstate] = React.useState({ firstname: "", lastname: "" });
  const handleClick = (e) => {
    setstate(e.target.value);
    console.log(e.target.value);
  };

  return (
    <div>
      <input
        value={state.firstname}
        onChange={handleClick}
        placeholder="firstname"
      />
      <input
        value={state.lastname}
        onChange={handleClick}
        placeholder="lastname"
      />
    </div>
  );
};

export default FunctionalInput;

Код выше показывает, как пользоваться хуком useState для управления состоянием в функциональном компоненте.

useEffect

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

import React, { useEffect } from "react";

const FunctionalInput = () => {
  const [state, setstate] = React.useState({ firstname: "", lastname: "" });

  //This piece of code runs after the ui has been rendered
  useEffect(() => {
    console.log("A component was rendered!!!");
  }, []);

  const handleClick = (e) => {
    setstate(e.target.value);
    console.log(e.target.value);
  };

  return (
    <div>
      <input
        value={state.firstname}
        onChange={handleClick}
        placeholder="firstname"
      />
      <input
        value={state.lastname}
        onChange={handleClick}
        placeholder="lastname"
      />
    </div>
  );
};

export default FunctionalInput;

useEffect в коде выше будет вызван сразу после того, как будет отрисован UI. Вторым параметром в useEffect передается пустой массив – в этом случае метод в useEffect не будет вызываться каждый раз, когда перерисовывается UI. В useEffect можно делать запросы к API – каждый раз, когда перерисовывается UI и меняются параметры, которые влияют на данные, которые должны быть показаны – удобно запрашивать их именно в useEffect.

В React вы можете создавать свои собственные хуки – это дает широкие возможности для их применения. Но, используются они только в функциональных компонентах.

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

Leave a Comment

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

Scroll to Top