【问题标题】:react tabs call componentDidMount every time when switching tab每次切换选项卡时反应选项卡调用componentDidMount
【发布时间】:2017-03-05 23:20:15
【问题描述】:

我正在使用这个反应库:https://github.com/reactjs/react-tabs,我创建了一个像这样的简单组件:

export default class Sample extends Component {

    componentDidMount() {
        console.log("Mount");
    }

    render () {
    return (

            <div>
             Hello
            </div>
    );
  }
}

我已将它插入到示例应用程序的选项卡中:

import React, { Component } from 'react';
import { render } from 'react-dom';
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import Sample from './Sample.jsx';

class App extends Component {
  handleSelect(index, last) {
    console.log('Selected tab: ' + index + ', Last tab: ' + last);
  }

  render() {
    return (


      <Tabs
        onSelect={this.handleSelect}
        selectedIndex={2}
      >

        <TabList>

          <Tab>Foo</Tab>
          <Tab>Bar</Tab>
          <Tab>Baz</Tab>
        </TabList>

        <TabPanel>
          <Sample />
        </TabPanel>
        <TabPanel>
          <Sample />
        </TabPanel>
        <TabPanel>
          <Sample />
        </TabPanel>
      </Tabs>
    );
  }
}

render(<App/>, document.getElementById('container'));

每次切换 Tab 时都会调用 componentDidMount,我可以在控制台中看到 Mount 登录。我的问题是如何避免每次都调用componentDidMount 方法,但只在第一次调用它?我提出这个问题是因为我想在其中添加一个 Ajax 调用,并且我不想每次切换选项卡时都进行 Ajax 调用,但只进行一次。

谢谢

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您可以在&lt;Tabs/&gt; 组件上使用forceRenderTabPanel={true} 以使选项卡保持挂载状态。

    <Tabs
      onSelect={this.handleSelect}
      selectedIndex={2}
      forceRenderTabPanel={true}
    >
    

    【讨论】:

    • 感谢您的回答,是的 forceRenderTabPanel 只挂载一次并没有卸载它,问题是隐藏的选项卡没有正确的样式,例如未加载的宽度正确.有没有办法重新加载样式?
    • 我认为这是一个 CSS 问题。样式不需要重新加载。
    • forceRenderTabPanel={true},至少在我的情况下,意味着在安装任何选项卡时进行 Ajax 调用,这只是不可用。
    • Same here using forceRenderTabPanel={true} 表示即使用户没有单击它们也会加载所有表,因此如果您有一个包含大量数据要加载的选项卡,此组件将一直卡住直到 get即使用户不需要这些数据。
    【解决方案2】:

    我也遇到了同样的问题。您的所有组件需要同时存在并使用 this.STATE.tabIndex 和 CSS 来控制不可见性。

    使用受控模式创建选项卡:

    class App extends Component {
      constructor() {
        super();
        this.state = { tabIndex: 0 };
      }
      render() {
        return (
          <Tabs onSelect={tabIndex => this.setState({ tabIndex })}>
            <TabList>
              <Tab>Title 1</Tab>
              <Tab>Title 2</Tab>
            </TabList>
            <div style={this.state.tabIndex===0 ? 
              {display:"block"}: {display:"none"}} >
            </div>
            
            <div style={this.state.tabIndex===0 ? 
              {display:"block"}: {display:"none"}} >
            </div>
    
          </Tabs>
        );
      }
    }

    【讨论】:

    • 你不能用forceRenderTabPanel={true}得到同样的行为
    • 这里唯一要记住的是不要像上面那样使用 TabPanel 和使用 Divs。
    【解决方案3】:

    每次 React 将组件添加到 DOM 时,componentDidMount都会触发,这是没有办法的。

    在您的情况下,当您切换选项卡时,我假设 React 卸载 TabPanel 组件的当前内容并 安装 新内容,即您的 @ 987654323@ 组件,反过来,一旦安装,将触发componentDidMount 方法。

    根据您的 AJAX 调用返回的内容,您可能应该重新考虑放置 AJAX 调用的位置。

    【讨论】:

    • 我可以把它放在哪里?
    • 我假设您正在获取 TabPanel 内容,对吗?所以你可以用几种方法来处理它。例如,一种方法是将 Ajax 调用放在 Tabs 的 componentDidMount 中。在任何情况下,请检查 react-tabs 的 forceRenderTabPanel 属性的作用,因为它可能只允许您安装选项卡内容一次,而无需卸载
    • 感谢您的回答,是的 forceRenderTabPanel 只挂载一次并没有卸载它,问题是隐藏的选项卡没有正确的样式,例如未加载的宽度正确.有没有办法重新加载样式?
    • 隐藏标签的样式不正确是什么意思?不可见就足够了,不是吗?无论如何,它们的样式应该在 CSS 中定义,所以我无法想象这里有什么问题
    猜你喜欢
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 2018-12-23
    • 2016-03-13
    相关资源
    最近更新 更多