有人告诉我,最好的做法是只对容器使用类,对组件使用函数。因此,容器具有状态,组件是愚蠢的功能,只能接收和向容器发送道具或从容器发送道具。
我发现的问题是,这会导致容器真正膨胀。不仅如此,如果容器包含许多不同的组件,那么这些容器中的方法就是许多不同的不相关功能的混合体。
这与保持所有模块高度模块化的想法背道而驰。例如,如果我的容器中有一个“提交评论”组件,则我希望SubmitCommentHandler方法也位于相关的组件中,并且不会与大量其他不相关功能的处理程序在Post容器中混合在一起,例如在ratePostHandler和userLoginHandler。
我是新来的反应者,所以也许我错过了一些东西,但是如何使这种“最佳实践”与它提出的所有其他问题相协调呢?
答案 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组成的容器的屏幕截图: