Реквизит и состояние в React

React понравился мне, когда я начал думать об HTML-элементах как о компонентах, а атрибуты для этих элементов — как о свойствах. Вместо дерева DOM вы получите дерево компонентов React с аналогичной структурой и аналогичной семантикой, и вы сможете передавать данные или конфигурацию этим компонентам с помощью свойств.

Состояние в основном полезно для двух вещей:

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

И свойства, и состояние представлены «простыми старыми объектами JavaScript», где ключи — это строки, а значения могут быть любыми. Таким образом, реквизит — это не строго строковое или логическое значение, как в HTML-атрибутах — скорее, это могут быть объекты JavaScript, функции обратного вызова или что-то еще, что вы можете придумать и выразить в JS. На самом деле, термин «реквизиты рендеринга» — это просто метод, при котором вместо того, чтобы давать React кучу компонентов React для рендеринга, вы передаете функцию в качестве реквизита (и позволяете вызывать функцию для возврата компонентов React).

Состояние обычно поднимается как можно выше в дереве компонентов и используется только тогда, когда это необходимо (большинство кодовых баз не содержат 50–50 свойств состояния, они в подавляющем большинстве случаев являются реквизитами). Довольно часто можно увидеть компоненты с состоянием вверху, и эти компоненты просто передают данные ниже компонентам, которые принимают только реквизиты и используют эти реквизиты только для отображения данных. Это разделение иногда называют умными и тупыми компонентами. Умные компоненты — это компоненты, которые сохраняют состояние и имеют в себе определенную логику (логика данных внутри них — это то, что делает их умными). Тупые компоненты — это компоненты, которые по своей природе являются презентационными, то есть они просто отображают данные без каких-либо побочных эффектов, обычно используются повторно и часто не имеют никакого внутреннего состояния. (Этот термин был придуман в этом основополагающем посте Дэна Абрамова.)

Компоненты, не имеющие внутреннего состояния, могут быть представлены иначе, чем в традиционном синтаксисе классов React. Они могут быть написаны как нечто, известное как функциональный компонент без состояния или SFC. Преимущество SFC заключается в том, что React может оптимизировать их производительность в будущем, поскольку они указывают React, что они проще, чем компоненты (которые могут иметь внутреннее состояние, а также различные части жизненного цикла, за которыми нужно следить). Они также позволяют вам избегать API-интерфейсов, специфичных для React, которые могут позволить вам переключаться между React и другими основанными на компонентах библиотеками, вдохновленными React (например, Inferno или Preact).

Одним из недостатков SFC является то, что они не работают с методами жизненного цикла, поэтому, если вам нужно указать метод жизненного цикла, вам придется вернуться к синтаксису класса. SFC также, возможно, вопреки ожиданиям, в настоящее время не оптимизируются в зависимости от того, изменились реквизиты или нет (в настоящее время они перерисовываются каждый раз при изменении реквизитов, что является поведением по умолчанию shouldComponentUpdate в синтаксисе класса).

[С появлением React Hooks функциональные компоненты теперь также могут обрабатывать перехватчики состояния и жизненного цикла.]