最佳实践会导致容器膨胀和非模块化代码

时间:2018-08-05 19:43:39

标签: javascript reactjs design-patterns

有人告诉我,最好的做法是只对容器使用类,对组件使用函数。因此,容器具有状态,组件是愚蠢的功能,只能接收和向容器发送道具或从容器发送道具。

我发现的问题是,这会导致容器真正膨胀。不仅如此,如果容器包含许多不同的组件,那么这些容器中的方法就是许多不同的不相关功能的混合体。

这与保持所有模块高度模块化的想法背道而驰。例如,如果我的容器中有一个“提交评论”组件,则我希望SubmitCommentHandler方法也位于相关的组件中,并且不会与大量其他不相关功能的处理程序在Post容器中混合在一起,例如在ratePostHandler和userLoginHandler。

我是新来的反应者,所以也许我错过了一些东西,但是如何使这种“最佳实践”与它提出的所有其他问题相协调呢?

1 个答案:

答案 0 :(得分:3)

您的帖子中存在一些误解,可能是由于您正在阅读的最佳实践文章中的误解所致。

当容器+组件的核心思想开始浮出水面时,许多示例并未正确地做到这一点。

// DO NOT DO THIS

let FormComponent = ({ data, handleSubmit }) =>
  <form onSubmit={handleSubmit}>
    {...something with data...}
  </form>

class FormContainer extends React.Component {
  state = { data: [] }
  submitForm = formData => {
    api.post(formData).then(data => this.setState({ data }))
  }
  render() {
    return (
      <div>
        <FormComponent 
          data={this.state.data} 
          handleSubmit={this.submitForm} 
        />
      </div>
    )
  }
}

这是一个非常经典的容器+组件示例,但是 100%无用,并且与整个想法背道而驰。为了使容器模块化,它们需要与呈现逻辑完全无关。如果您将演示文稿硬编码在容器中,那么这只是一个大组件,分为两部分,我可能会任意添加。

您可以阅读有关高阶组件的信息,但我将重点关注越来越受欢迎的标准:render props

class FormContainer extends React.Component {
  state = { data: [] }
  submitForm = formData => {
    api.post(formData).then(data => this.setState({ data }))
  }
  render() {
    return this.props.children({ 
      data: this.state.data, 
      submitForm: this.submitForm 
    })
  }
}

现在,您有一个容器可以执行一项操作,并且可以在应用程序中的任何位置重复使用它,并且可以使用任何演示组件,例如:

let SomewhereInYourApp = () => (
  <FormContainer>
    {({ data, submitForm }) => (
      <div> 
       {/* put whatever you want here.. it's modular! */}
       <FormComponent data={data} handleSubmit={submitForm} />
      </div>
    )}
  </FormContainer>      
)

然后,您可以根据需要创建任意数量的容器,这些容器仅执行对它很重要的特定业务逻辑并将其嵌套,但是这样做很有意义。我认为没有最佳实践可以将所有内容组合到一个容器中。嵌套容器是完全可以接受的。

如果您有很多容器,并且嵌套有点像金字塔,请考虑使用HoC或react-adopt之类的实用程序来组成使用渲染道具的容器。

react-adopt组成的容器的屏幕截图:

enter image description here