В редакцию пришло письмо: "не могли бы вы подробно разъяснить…"
Применение описанных ниже практик можно пощупать тут.
Сначала были компоненты на классах:
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/
Добавить комментарий