В React отсутствует какое-либо наследование компонентов, так что если необходимо реализовать несколько компонентов с похожим функционалом (и одинаковым кодом), и избежать копирования общего кода, то для этого существует только два способа повторного использования кода:
Особенности:
- Mixin (docs)
- Компонент-обёртка
Например, мы хотим одинаковым образом обрабатывать реакцию на мышь у разных компонентов.
var Sortable = {
componentDidMount: function() {
this._clearSortState();
},
sortMouseDown: function(event) {
this.sortableMouseDownTarget = event.target;
},
...
sortEnd: function() {
...
if (this._isDropFinished) {
this.sortItems(this.sortState.key, this.sortState.overKey, this.sortState.placeAfter);
}
...
}
};
var SomeComponent = React.createClass({
mixins: [Sortable],
componentDidMount: function() {
...
},
sortItems: function(key, overKey, placeAfter) {
...
},
render: function() {
return <div onMouseDown={this.sortMouseDown}>...</div>;
}
});
var SomeOtherComponent = React.createClass({
mixins: [Sortable],
sortItems: function(key, overKey, placeAfter) {
...
},
render: function() {
return <ul onMouseDown={this.sortMouseDown}>...</ul>;
}
});
Особенности:
- Стандартные методы цикла жизни (componentDidMount, componentWillUnmount и т.п.) не перезатираются, а объединяются с такими же методами в компоненте, т.е. если и у компонента и у использованных миксинов есть метод componentDidMount, то все они будут вызваны по очереди: сначала методы миксинов в том порядке, в котором миксины были указаны в массиве mixins, затем метод собственно компонента.
- Все прочие имена полей/методов в миксине должны быть уникальными, т.е. если и миксин и использующий его компонент будут содержать метод sortMouseDown, то React сообщит об ошибке в консоли браузера.
- Не создаёт никаких дополнительных элементов и уровней вложенности.
Элемент-обёртка
Например, подгрузка бесконечного списка при прокрутке вниз.
var InfiniteScroll = React.createClass({
componentDidMount: function() {
this.attachScrollListener();
},
componentDidUpdate: function() {
this.attachScrollListener();
},
render: function() {
var props = this.props;
return React.DOM.div(null, props.children, props.hasMore && props.loader);
},
scrollListener: function() {
...
if (scrollParent.scrollHeight - $(scrollParent).scrollTop() - $(scrollParent).height() < this.props.threshold) {
this.props.loadMore(this.pageLoaded += 1);
}
},
...
componentWillUnmount: function() {
this.detachScrollListener();
}
});
var MyEndlessList = React.createClass({
loadMore: function(page) {
...
},
...
render: function() {
return (
<div style={{maxHeight: '500px', overflowY: 'auto'}}>
<InfinityScroll
ref="scroll"
loadMore={this.loadMore}
hasMore={this.state.hasMore}>
{this.state.items}
</InfinityScroll>
</div>
);
}
});
Особенности:
- Лишний уровень вложенности как в JSX, так и в DOM.
- Все необходимые параметры и настройки обёртки собраны в одном месте - в атрибутах обёртки.
- Проблемы конфликта имён, как в миксине, не существует в принципе.
Комментариев нет:
Отправить комментарий