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


Как говорится, в редакцию пришло письмо: «не могли бы вы подробно разъяснить…» Отвечаю публично, кому оно надо, а применение можно пощупать тут.


Сначала были компоненты на классах:


class Square extends React.Component {
  constructor() {
    super()
    this.state = {
      value: null,
    }
  }
  render() {
    const { value, onClick } = this.props
    return (
      
    )
  }
}

Потом явились функциональные компоненты:


const Square = ({ value, onClick }) => {(
  
)}

В чём разница? Выкидываем: объявление класса, constructor (), render (), const для деструктуризации props, this. А ещё исчезло состояние компонента — мы получаем stateless functional components.


Как дальше жить без локального состояния: 1) или применять функциональные компоненты только там, где не нужно хранить состояние; 2) или перенести всё состояние в стор redux-а (как единственный источник правды). Локальные состояния компонентов — это дополнительный уровень абстракции, требующий обслуживания. А зачем?


Ещё желательно преодолеть коннектобоязнь — не тащить все свойства через родительские компоненты, а применять connect () для дочерних компонентов по мере использования свойств.


Разобрались, а как же применить PureComponent к функциональным компонентам? На помощь приходит техника Higher-Order Components:


// utils.js
import React from 'react'

export const pureComponent = (fn) => {
  class Wrapper extends React.PureComponent {
    render() {
      return fn(this.props, this.context)
    }
  }
  // не надо, т.к. подписывает на контекст как и функциональный компонент,
  // так и оболочку-PureComponent; лучше назначать сразу оболочке (снаружи)
  // Wrapper.contextTypes = fn.contextTypes
  Wrapper.displayName = fn.name
  return Wrapper
}

Присваивание displayName — для красоты в React DevTools. Подробнее про contextTypes можно почитать тут.


Пример использования:


import { pureComponent } from 'utils'

const Square = ({ value, onClick }) => {(
  
)}

export default pureComponent(Square)

Рекомендуемые статьи
  • Стрелочные функции
  • Руководство по работе с Redux

Комментарии (3)

  • 16 апреля 2017 в 20:18

    0

    Забивать редакс всяким мусором не лучшая идея…
  • 16 апреля 2017 в 23:45

    +1

    Раз уж тут речь идет о функциональных компонентах, полезным будет упомянуть библиотеки recompose и recompact.


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

  • 17 апреля 2017 в 00:48

    0

    Можно через HOC и statefull функциональные компоненты делать.

© Habrahabr.ru