最佳实践:使用props.children封装组件或深入构建

时间:2015-02-02 15:36:43

标签: reactjs react-jsx

我面临着如何撰写我的组件的决定,我想知道社区是否有关于哪种是最佳实践的想法。

1:封装组件以隐藏详细信息。

所有者呈现:

<List ... />

列表渲染:

<Item ... />

项目渲染:

<div>...</div>

在这个版本中,组件不是非常可重用,因为他们知道很多域详细信息。所有者对列表中的项目一无所知。

2:将组件嵌入顶部有状态视图控制器

附近

所有者呈现:

<List>
  <Item>
    <div>...</div>
  </Item>
</List>

在这个版本中,所有者知道它的子组成,但组件本身并不是很有用,因为它们对域名一无所知。然而,它们更可重复使用。

3:在域特定组件中封装通用组件

这是选项1和选项2的混合

所有者呈现:

<DomainList ... />

DomainList呈现:

<List ...>
  <DomainItem .../>
</List>

DomainItem呈现:

<Item ...>
   ...
</Item>

所有者对通用List,DomainItem或通用项目一无所知。

哪种方法更好?有没有人使用这些方法成功或失败?发生了什么事?

1 个答案:

答案 0 :(得分:2)

组件的可重用性并不是因为它们决定了它们应该如何呈现的大部分内容。您甚至可以争辩说它们更可重用,因为使用它的组件不需要知道它如何渲染。

当你开始考虑这些事情时,通过分析状态很容易陷入瘫痪状态。我创建React组件的方法是:

  1. 尽量避免在组件中使用状态,并将状态作为props传递给层次结构中的较高层。
  2. 仅对不知道内容包含哪些内容的包装组件使用this.props.children。常见的东西,如弹出窗口,标签视图等。
  3. 不要开始将东西提取到其他组件中,因为“我可能会在以后的其他地方重复使用它”。相反,我只提取一次,我知道我需要它在其他地方。
  4. 我尝试像组件的用户一样思考,而不是像那个组件的作者那样思考。问问自己“如何将数据传递给该组件?”,“当组件发生变化时,是否需要提醒该组件的用户?”,“使用此组件需要多大的灵活性?” 。虽然很容易在这里进行推广,所以我也尽量不抽象过多。
  5. 我倾向于看到两种不同类型的组件。通用的东西要么是如此通用,以至于我可以在项目或特定于应用程序之间重用它们但是足够通用,我将在应用程序的不同部分中将它们用于不同目的。 然后是具有非常特定目的的特定组件,例如“渲染此待办事项列表”或“渲染此表单以编辑待办事项”。这些往往使用通用组件,但绝对不是相反。

    当我开始创建这些类型的组件时,我通常都知道。对于通用组件,我倾向于使它们尽可能灵活和开放。对于特定目的,我把它们更像黑盒子,有点像“只是给我数据,我会从那里拿走它”。因为它们具有非常具有描述性的名称并且知道如何自我渲染,所以在阅读使用它们的代码时很容易理解正在发生的事情。

    在你的例子中,我会说List组件是一个通用组件,我肯定想让它变得灵活。我可能有一个特定的组件用于我正在构建的列表,类似于TodoList,可能类似于:

    var TodoList = React.createClass({
      render() {
        return (
          <List>
            {this.props.todos.map(todo => <ListItem>{todo.text}</ListItem>)}
          </List>
        );
      }
    });
    

    另一种选择是这样的:

    var ListItem = React.createClass({
      render() {
        return <li>{this.props.item.text}</li>;
      }
    });
    
    var TodoList = React.createClass({
      render() {
        return <List items={this.state.items} listItemComponent={ListItem} />;
      }
    });
    

    在这种情况下,List组件会遍历所有项目,并使用传递的listItemComponent组件来呈现项目。

    <强> TL; DR

    首先制作非常了解的非常具体的组件,并在看到用例重用时重构它们。