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

时间:2016-03-30 18:30:14

标签: javascript reactjs redux

我花了很多时间考虑如何在React中尽可能干净地构建最好的东西。最近我一直在讨论React容器是否应该什么也不做,只能连接到Redux(或其他数据 - 流星)并渲染/返回单个组件,或者容器是否也应该负责事件处理同样。例如,它是这两种模型之间的折腾:

模型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,还要处理事件,触发componentDidMount中的Ajax请求等。使用第一个模型,如果我想要一个要在componentDidMount中调用Ajax请求,它必须进入Thing并且看起来不对。

我想知道这些方法中是否存在任何特定的优点或缺陷,或者它是否归结为风格/偏好。

1 个答案:

答案 0 :(得分:15)

在“presentational-ish”Thing中进行AJAX时没有任何内在错误,因为它只有几种方法,而且这个组件从不在不同场景中使用过。在您确定 行为在不同情境中的变化之前,请不要从演示文稿中拆分行为。

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

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