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

от автора

В редакцию пришло письмо: "не могли бы вы подробно разъяснить…"

Применение описанных ниже практик можно пощупать тут.

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

class Square extends React.Component {   constructor() {     super()     this.state = {       value: null,     }   }   render() {     const { value, onClick } = this.props     return (       <button className="square" onClick={onClick}>         {value}       </button>     )   } }

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

const Square = ({ value, onClick }) => {(   <button className="square" onClick={onClick}>     {value}   </button> )}

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

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

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

// utils.js  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 }

Про contextTypes можно почитать тут: "If contextTypes is not defined, then context will be an empty object".

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

import { pureComponent } from 'utils'  const Square = ({ value, onClick }) => {(   <button className="square" onClick={onClick}>     {value}   </button> )}  export default pureComponent(Square)

Рекомендуемые статьи

ссылка на оригинал статьи https://habrahabr.ru/post/326610/