我可以将 AJAX 调用放在表示组件中,还是应该提取容器

Can I put AJAX calls in the presentational component, or should I extract a container?

本文关键字:提取 调用 AJAX 组件 表示 我可以      更新时间:2023-10-17

我花了很多时间思考如何在 React 中尽可能干净地构建事物。最近我一直在纠结 React 容器是否应该什么都不做,只是连接到 Redux(或其他数据 - 就像 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在某种意义上变成了自己的容器,我不确定我是否喜欢。Model 2 感觉更自然,因为 ThingContainer 不仅负责处理数据和 Redux,还负责处理事件、在 componentDidMount 中发出 Ajax 请求等。对于第一个模型,如果我想在 componentDidMount 中调用 Ajax 请求,它必须进入Thing这似乎不正确。

我想知道这两种方法是否有任何特别的优点或陷阱,或者它是否只是归结为风格/偏好。

当它只有几个方法时,在"表示式"Thing中执行 AJAX 本身并没有什么错,而且无论如何,此组件从未在不同的场景中使用过。在确定行为在不同上下文中如何变化之前,不要将行为与演示文稿分开。

您遇到这种困境意味着您的组件还不需要重用。在这种情况下,如何拆分它并不重要。这两种方式都可以正常工作,所以我会选择更简单的一种(模型 1(。

稍后您可能会意识到,您希望重用相同的外观,但触发不同的 AJAX 调用,或者以不同的方式计算道具。此时,您可能希望从Thing中删除事件处理并创建几个不同的ThingContainer,每个处理事件和计算道具略有不同。这是将呈现和行为分开变得有用的时候。