Могу ли я поместить вызовы 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, причем каждый процесс обработки событий и расчетные реквизиты немного по-другому. Это когда разделение представления и поведения становится полезным.