Доброго времени суток друзья. Как часто вы создаете компоненты и вам приходится повторять одинаковый функционал? На практике, если вам нужно создать кнопку которая будет что-то открывать и в следующем компоненте опять же будет кнопка которая будет что-то открывать, стоит задуматься о декораторах.
Декораторы в React это отличный способ оптимизации вашего приложения путем сокращения дублирующих элементов. На практике это функция которая будет принимать на входе текущий компонент и просто оборачивать его с верху компонентом оберткой с состоянием и возможными событиями.
Хватит теории, давай перейдем к практике и напишем свой первый декоратор.
Для примера мы возьмем такой кейс. Допустим у нас есть список статей, каждая статья будет открываться по клику на кнопку. В открытой статье есть кнопка показать комментарии. Фунционал открытия статей и комментариев одинаковый и что бы не плодить сущности мы воспользуемся декоратором.
Пример списка статей
class ComponentList extends Component {
constructor(props){
super(props)
this.state = {
isOpen: false,
}
this.toggleClick = this.toggleClick.bind(this)
}
render(){
const { comments, isOpen } = this.props
const { isOpen } = this.state
return(
<div>
{comments.length ? <button onClick={this.toggleClick}>{isOpen ? 'hidden': 'show'}</button> : null}
{this.getBody()}
</div>
)
}
getBody(){
const { comments } = this.props
const { isOpen } = this.state
if(!isOpen) return null
return (
<ul>
{comments.map(item => <li key={item.id}><Comment comment={item}/></li>)}
</ul>
)
}
toggleClick(ev){
ev && ev.preventDefault() && ev.preventDefault
this.setState({
isOpen: !this.state.isOpen
})
}
}
export default ComponentList
Этот компонент достаточно простой. Его главная задача отрендерить список статей. В старте компонента мы храним состояние кнопки. Еще у нас есть функция события которая висит на самой кнопки. Наша задача этот функционал компонента перенести в декоратор для дальнейшего переиспользования.
Пример декоратора
import React, {Component} from 'react'
export default (OriginalComponent) => class WrapperComponent extends Component {
constructor(props){
super(props)
this.state = {
isOpen: false,
}
this.toggleClick = this.toggleClick.bind(this)
}
render(){
return <OriginalComponent {...this.state} toggleClick={this.toggleClick} {...this.props} />
}
toggleClick(ev){
ev && ev.preventDefault() && ev.preventDefault
this.setState({
isOpen: !this.state.isOpen
})
}
}
Данная функция на входе принимает оригинальный компонент и делает обертку его другим компонентом. Последнее что нам нужно сделать это заимпортировать данный декоратор и обернуть его в текущей компонент.
export default toggleOpen(ComponentList)
Теперь в ComponentList мы можем вытащить из this.props все нужные нам данные и заменить их в самом компоненте.
class ComponentList extends Component {
static defaultProps = {
comments: []
}
static PropsTypes ={
comments: PropTypes.string
}
constructor(props){
super(props)
}
render(){
const { comments, isOpen, toggleClick } = this.props
return (
<div>
{comments.length ? <button onClick={toggleClick}>{isOpen ? 'hidden': 'show'}</button> : null}
{this.getBody()}
</div>
)
}
getBody(){
const { comments, isOpen } = this.props
if(!isOpen) return null
return (
<ul>
{comments.map(item => <li key={item.id}><Comment comment={item}/></li>)}
</ul>
)
}
}
export default toggleOpen(ComponentList)
Заключение
Сегодня мы изучили декораторы в React. Написали простой пример декоратора для списка статей. Надеюсь что данная статья была вам полезна. Удачно покодить!)
Подписывайтесь на наш канал в Telegram и на YouTube для получения самой последней и актуальной информации.
Обычно, React становится медленным не из-за одного медленного компонента (что будет отображено на графике, как одна большая яма). В большинстве же случаев, React становится медленным из-за бесполезной перерисовки множества компонентов.
Я не думала что найду, спасибо большое!
Спасибо за информацию.
Добрый день спасибо за информацию