Могу ли я поместить вызовы AJAX в презентационный компонент или извлечь контейнер?
Я провожу много времени, думая о том, как наилучшим образом структурировать вещи как можно чище в React. В последнее время меня повесили трубку, если контейнеры React не должны ничего делать, кроме подключения к Redux (или другим данным - a la Meteor), а также для рендеринга/возврата отдельного компонента или если контейнеры также должны отвечать за обработку событий, Так, например, это происходит между этими двумя моделями:
Модель 1
// ThingContainer.js
import Thing from '../components/Thing';
export default someHigherOrderFunc(/* map state/data to props */)(Thing)
// Thing.js
export default class Thing extends Component {
handleClick() { /* ... */ }
handleMouseEnter() { /* ... */ }
render() {
// Other components rendered here, both container or presentational
}
}
Модель 2
// ThingContainer.js
class ThingContainer extends Component {
handleClick() { /* ... */ }
handleMouseEnter() { /* ... */ }
render() {
// Now Thing can be stateless
return <Thing
onClick={this.handleClick}
onMouseEnter={this.handleMouseEnter}
/>
}
}
export default someHigherOrderFunc()(ThingContainer)
Это почти похоже на модель 1, Thing
становится его собственным контейнером в некотором смысле, который я не уверен, что мне нравится. Модель 2 выглядит более естественной, так как ThingContainer
заряжается не только обработкой данных и Redux, но и обработкой событий, сбрасыванием запросов Ajax в componentDidMount
и т.д. С первой моделью, если бы я хотел, чтобы запрос Ajax был вызывается в componentDidMount
, он должен войти в Thing
, который не выглядит правильным.
Мне интересно, есть ли какие-либо особые преимущества или подводные камни для любого из этих подходов, или если это просто сводится к стилю/предпочтениям.
Ответы
Ответ 1
Нет ничего по своей сути неправильно делать AJAX внутри "presentational-ish" Thing
, когда его только несколько методов, и этот компонент никогда не используется в разных сценариях в любом случае. Не разделяйте поведение из презентации, прежде чем вы убедитесь, как поведение изменяется в разных контекстах.
То, что у вас есть эта дилемма, означает, что ваш компонент еще не должен использоваться повторно. В этом случае не имеет значения, как вы его разделяете. Оба способа работают нормально, поэтому Id переходит на более простой (модель 1).
Позже вы поймете, что хотите повторно использовать один и тот же внешний вид, но запускаете различные вызовы AJAX или иначе вычисляете реквизиты. На этом этапе вам может потребоваться удалить обработку событий из Thing
и создать несколько разных ThingContainer
s, причем каждый процесс обработки событий и расчетные реквизиты немного по-другому. Это когда разделение представления и поведения становится полезным.