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


我花了很多时间考虑如何在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,还要处理事件,解雇Ajax请求 componentDidMount使用第一个模型,如果我想要调用Ajax请求 componentDidMount,它必须进去 Thing 这似乎不对。

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


12078
2018-03-30 18:30


起源



答案:


在“表现形式”中进行AJAX没有任何内在错误 Thing 当它只有几种方法时,这个组件从不用于不同的场景。在您确定之前,不要将行为从演示文稿中分离出来 怎么样 行为在不同的背景下发生变化。

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

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


12
2018-03-30 18:45



您似乎对React + Redux有一些经验;) - markthethomas
这很有道理!然后,如果我想拥有可以全部包装的不同容器 Thing,它只是归结为一个命名约定的问题(如何命名几个变体 ThingContainer)。 - ffxsam
是啊。我发现命名不是真实用例的问题。例如。 List VS UserFollowerList, UserFollowingList, UserPostList等 - Dan Abramov


答案:


在“表现形式”中进行AJAX没有任何内在错误 Thing 当它只有几种方法时,这个组件从不用于不同的场景。在您确定之前,不要将行为从演示文稿中分离出来 怎么样 行为在不同的背景下发生变化。

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

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


12
2018-03-30 18:45



您似乎对React + Redux有一些经验;) - markthethomas
这很有道理!然后,如果我想拥有可以全部包装的不同容器 Thing,它只是归结为一个命名约定的问题(如何命名几个变体 ThingContainer)。 - ffxsam
是啊。我发现命名不是真实用例的问题。例如。 List VS UserFollowerList, UserFollowingList, UserPostList等 - Dan Abramov