反应的Tabs组件

时间:2016-07-19 03:18:33

标签: reactjs react-router

我已经扫描了react-bootstrap的Tabs组件,但它不是一个好选择,它在Tabs Component安装后挂载了所有选项卡。所以我使用子路径制作Tabs组件。

我有三个标签。例如,tabA,tabB,tabC。

特别地,tabA和tabB具有相同的UI,但它们请求不同的API

<Route path="tabs" getComponent={ProfitReports.flag.detail.default}>
    <Route path="tabA" getComponent={tabAorB}/>
    <Route path="tabB" getComponent={tabAorB}/>
    <Route path="tabC" getComponent={tabC}/>
</Route>

....

class Tabs extends React.Component {
    render() {
        return (
            <Flex className="gm-tabs gm-paddingLR15">
                <IndexLink to="/tabs/tabA" className="tab" activeClassName="active">TabA</IndexLink>
                <Link to="/tabs/tabB" className="tab" activeClassName="active">TabB</Link>
                <Link to="/tabs/tabC" className="tab" activeClassName="active">TabC</Link>
            </Flex>
        );
    }
}

export default Tabs;

但问题来了。

当我单击tabA链接时,它可以正常工作,但是当我单击tabB链接时,除了url已更改之外没有任何反应。没有请求,没有新组件init

我发现TabAorB组件没有卸载,所以我想也许问题就在这里。

要求

我希望:

我单击tabA链接,它会请求API1,并在单击tabB链接后请求API2

3 个答案:

答案 0 :(得分:0)

您的路线可能存在冲突或配置错误。但是,对我来说,使用路由器看起来不像是标签的干净解决方案。这是使用bootstrap 3的项目中使用的制表符组件:

import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';


export default class Tabs extends React.Component {
  componentDidMount() {
    this.panelsContainer = $(ReactDOM.findDOMNode(this.refs.panelsContainer));
    this.tabsContainer = $(ReactDOM.findDOMNode(this.refs.tabsContainer));
    this.panels = this.panelsContainer.find('.panel-tab');
    this.tabs = this.tabsContainer.find('li');
    this.tabs.eq(0).addClass('active');
    this.panels.eq(0).css(this._styles.panelActive);
    this.panelsContainer.height(this.props.minHeight);
  }


  _handleClick(e) {
    const panel = $(ReactDOM.findDOMNode(this.refs[e.target.dataset.toggle]));
    const tab = $(e.target).parent();

    this.tabs.removeClass('active');
    tab.addClass('active');

    this.panelsContainer.height(panel.height());
    this.panels.css(this._styles.panel);
    panel.css(this._styles.panelActive);
  }

  _styles = {
    panel: {
      visibility: 'hidden',
      width: '100%',
      position: 'absolute',
      background: '#fff',
      border: '1px solid #ddd',
      borderTop: 'none',
    },
    panelActive: {
      visibility: 'visible',
      top: 0,
      left: 0,
    },
    panelsContainer: {
      position: 'relative',
    },
  };


  render() {
    let count = 0;

    const tabs = (
      <ul className="nav nav-tabs" ref="tabsContainer">
        {this.props.tabsNavItems.map((tab, key) =>
          <li key={key}><a href="javascript:void(0)" onClick={this._handleClick.bind(this)} data-toggle={++count}>{tab.tag}</a></li>
        )}
      </ul>
    );

    count = 0;

    const tabPanes = (
      <div style={this._styles.panelsContainer} ref="panelsContainer">
        { React.Children.map(this.props.children, (child) =>
          <div className="panel-tab" style={this._styles.panel} ref={++count}>
            { child }
          </div>
        )}
      </div>
    );

    return (
      <div >
          { tabs }
          { tabPanes }
      </div>
    );
  }
}

Tabs.propTypes = {
  tabsNavItems: React.PropTypes.array.isRequired,
};

然后你可以像这样使用它:

 _tabsNavItems = [
    { tag: 'Tab A' },
    { tag: 'Tab B' },
 ]
...

<Tabs tabsNavItems={this._tabsNavItems} minHeight={375}>
 <TabAContent />
 <TabBContent />
</Tabs>

答案 1 :(得分:0)

我在shouldComponentUpdate

中请求api解决了这个问题

答案 2 :(得分:0)

我今天偶然发现了这一点,现在看来他们已经在Tabs的{​​{1}}修复了此问题,因此您不必使用react-bootstrap。< / p>

您应该在react-router组件上传递属性unmountOnExit,并且只有当组件处于活动状态时,组件才会挂载。

参考文献: