React - 如何在render函数中返回几个组件之一?

时间:2016-12-05 23:50:50

标签: javascript reactjs

在我的州,我有showTab1showTab2showTab3。如果选择了选项卡i,则其他选项卡将设置为false。所以在我的render函数中,我希望能够返回这样的内容:

  return (
    <div>
      {
        (() => {
          if (someCondition) {
            if (this.state.showTab1) {
              return (
                <div>
                  <Tab1/>
                </div>
              )
            } else if (this.state.showTab2) {
              return (
                <div>
                  <Tab2/>
                </div>
              )
            } else if (this.state.showTab3) {
              return (
                <div>
                  <Tab3/>
                </div>
              )
            }
          }

          return <span />;
        })()
      }

      <AnotherComponent>
    </div>
  );

但我知道不允许多次退货,或者至少它被视为不良行为。我怎么能绕过这个?

2 个答案:

答案 0 :(得分:0)

理想情况下,您使用单个变量来确定所需的标签,然后您可以使用switch语句而不是多个if。这样的事情会很好:

render() {
    const { currentTabId } = this.props;
    let CurrentTab;
    switch( currentTabId ) {
        case 'tab1':
            CurrentTab = Tab1;
            break;
        case 'tab2':
            CurrentTab = Tab2;
            break;
        case 'tab3':
            CurrentTab = Tab3;
            break;
        default:
            CurrentTab = null;
    };
    return <div>{ CurrentTab && <CurrentTab /> }</div>;
}

render() {
    const { currentTabId } = this.props;
    const tabs = {
        tab1: Tab1,
        tab2: Tab2,
        tab3: Tab3,
    };
    const CurrentTab = tabs[ currentTabId ] || null;
    return <div>{ CurrentTab && <CurrentTab /> }</div>;
}

答案 1 :(得分:0)

您的标签有什么共同之处,是什么使其与其他标签不同?

考虑到这一点,创建一个Tab组件,该组件获取所需的属性(差异)并相应地呈现。但为什么?

React很棒,因为它可以知道DOM所需的最小更改量,以表示您设置的状态,允许您将整个UI作为基于状态的系统处理。 React的良好表现基于它能够说明这些差异的程度。

如果您的render方法每次都返回完全不同的组件,则React将remove one and append the other,因为它无法区分其中一个。但是,如果您使用属性和状态指定了哪些更改以及组件中没有更改的内容,那么它将很好地完成其工作。 DOM非常糟糕,一直以来,您所做的更改越少,页面的行为就越好。

这是否意味着您无法返回三个完全不同的组件?当然不是,但如果你在所有组件上都这样做,那么你会遇到非常严重的性能问题。这听起来非常像一个不好的做法,并且有足够的理由避免它。

将右边的SO标签作为一个非常简单的示例,并让您从页面中的其他位置导航到它们,因此只显示一个活动标签。

如果你这样做:

<div>
  {() => {
    if (this.state.active === 'jobs')
      return <Jobs>;
    if (this.state.active === 'doc')
      return <Documentation>;
    // ... you get it
  }}
</div>

每当您更改state.active时,React都会删除该标签,然后添加一个新标签。

但是如果你不使用不良做法,并使用像stateless functional components

这样的好习惯
const Tab = ({text, href, children}) => (
  <div>
    <a href={href}>{text}</a>
    {children}
  </div>
);

// In the parent one
textByTab() {
  switch(this.state.active) {
    case 'jobs':
      return 'Jobs';
    case 'doc':
      return 'Documentation';
  }
}

hrefByTab() { // ... you get it }

childrenByTab() {
  if (this.state.active === 'doc')
    return <span className="beta-thing">Beta</span>;
}

render() {
  return (
    <div>
      <Tab text={this.textByTab()} href={this.hrefByTab()}>
        {this.childrenByTab()}
      </Tab>
    </div>
  );
}

现在,React确切地知道什么可以改变,它如何改变,甚至可以do fancy functional stuff以获得更好的性能。