选项卡仅在第一次激活时挂载Tab内容

时间:2017-06-28 02:31:28

标签: reactjs react-bootstrap

我想仅在第一次激活时加载标签内容,之后内容保留在DOM中

这就是我所拥有的

  <Tabs defaultActiveKey={1} animation={false} id="my-tabs" mountOnEnter unmountOnExit>
    <Tab eventKey={1}>
      <div>content1</div>
    </Tab>
    <Tab eventKey={2}>
      <div>content1</div>
    </Tab>
  </Tabs>

它工作正常,但是切换标签之间存在延迟,因为我拥有的内容非常大,而且我想只在标签变为活动状态时呈现一次。

有没有办法实现这一目标?我正在使用react-bootstrap 0.30.10

3 个答案:

答案 0 :(得分:0)

这听起来像是一个很好的用例&#34;避免和解&#34; React提供的选项。

Here's a link to the relevant section in the documentation.

基本上,有一个名为shouldComponentUpdate的生命周期事件默认为true。当您将其更改为false时,它会告知React不要通过标准的对帐过程运行组件(即&#34;差异&#34;检查)。

与任何生命周期方法一样,您可以为它创建条件语句。

对于在第一次渲染后应该完全静态化的组件,这就是您所需要的:

class YourComponent extends React.Component {
  ...
  shouldComponentUpdate() {
    return false;
  }
  ...
}

但是,对于更一般的用例,您希望根据组件的props和/或状态编写条件语句:

class YourComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 
        // Your state
    };
  }

  shouldComponentUpdate(nextProps, nextState) {
        // A conditional statement to determine whether
        //    this component should check for updates or not
  }

  render () {
    return (
        <div>
          {/* Your JSX*/}
        </div>
    )
  }

答案 1 :(得分:0)

我没有使用React Boostrap,但我想它是基于组件设计的, 例如,呈现的内容使用TabIndex状态。仔细看看这个示例代码:

  renderActiveTabContent() {
    const { children } = this.props
    const { activeTabIndex } = this.state
    if (children[activeTabIndex]) {
      return children[activeTabIndex].props.children
    }
  }

因此,每次Tab状态被索引时,内容组件都会呈现。

您可以使用https://github.com/reactjs/react-tabs作为解决方案,另外明智地看一下这些代码来编写一个简单的代码,组件渲染一次并通过display:样式属性显示/隐藏状态。

希望它有所帮助。

答案 2 :(得分:0)

<强>更新

显然mountOnEnter必须与animation一起使用,否则无法正常使用。我做了改动,现在工作正常

旧答案

所以我想出了这个包装组件,如下所示

class TabsLazyLoad extends Component {

  constructor(props) {
    super(props);
    this.state = this.getInitialState();
    this.handleSelect = this.handleSelect.bind(this);
  }

  getInitialState() {
    return {
      key: this.props.key || this.props.defaultActiveKey,
      rendered: [],
    };
  }

  addRenderedTab(key) {
    const newState = _.cloneDeep(this.state);
    newState.rendered.push(key);
    this.setState(newState);
  }

  handleSelect(key) {
    this.setState({ key });
  }

  render() {
    return (
      <Tabs activeKey={this.state.key} onSelect={this.handleSelect} {...this.props}>
        {_.map(this.props.children, (tabComponent) => {
          if (_.includes(this.state.rendered, tabComponent.props.eventKey)) {
            return tabComponent;
          }
          if (tabComponent.props.eventKey === this.state.key) {
            this.addRenderedTab(this.state.key);
          }

          // if it's not rendered, return an empty tab
          const emptyTab = _.cloneDeep(tabComponent);
          emptyTab.props.children = null;
          return emptyTab;
        })}
      </Tabs>
    );
  }
}

TabsLazyLoad.propTypes = Tabs.propTypes;

它似乎工作正常,但我认为这有点hacky,但它是我现在能想到的最好的。