question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

<Tab /> re-renders child pane on switching.

See original GitHub issue

Steps

The default behavior of the <Tab /> component seems to be to remove it’s active <Tab.Pane> from the DOM every time it is made inactive, and to push it back in the DOM when it is selected and made active. This re-renders the child components of <Tab.Pane> and is a problem if you have children like Leaflet or CesiumJS which internally manage their display state, as this state is reset on every re-render.

Expected Result

One should expect that the default behavior would be to keep all Tab.Pane children rendered and in the DOM, and only display the one that is active. The inactive tabs should be hidden from the display while keeping them in the DOM.

Actual Result

Inactive Tabs get removed from the DOM and pushed in again when made active. This behavior breaks the flow of many stateful child components, by resetting their internal state.

Version

v0.71.0

Any quick fixes would be appreciated, while this gets fixed in main.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
levithomasoncommented, Jul 19, 2017

It seems that either behaviour (renderActiveOnly vs renderAll) could be justified

I would be OK supporting a single prop renderActiveOnly and default it to true so we have backward compatibility. Users can then renderActiveOnly={false} to render every tab.

Right now, we hard code the active className in TabPane.js. This will now need to become a prop. The Tab.js will then be able to choose to render all TabPanes and toggle the active prop or render a single Tab only (as it does currently).

1reaction
chinoycommented, Jul 19, 2017

I managed to get my desired behavior working by using a combination of <Menu /> and <Segment />. I set the CSS visibility property of the Segments to toggle based on the active Menu Item. Still, a little roundabout way to achieve this behavior, but it works. Looking forward to having a prop enabling this OTB.

Pasting code here for the benefit of anyone facing a similar issue with using <Tab />.

JSX

import React, { Component } from 'react';
import { Menu, Segment } from 'semantic-ui-react';
import classNames from 'classnames';

import Map from '../containers/Map/Map';
import Dashboard from '../containers/Dashboard/Dashboard';
import Team from '../containers/Team/Team';
import styles from './MainTabs.css';

class MainTabs extends Component {

  constructor(props) {
    super(props);

    this.state = {
      activePage: 'Map'
    }

  }

  handleMenuClick = (e, { name }) => {
    this.setState({ activePage: name });
  }
  render() {
    const { activePage } = this.state;

    let MapClass = classNames({
      'hidden': (activePage !== 'Map')
    });

    let DashboardClass = classNames({
      'hidden': (activePage !== 'Dashboard')
    });

    let TeamClass = classNames({
      'hidden': (activePage !== 'Team')
    });

    return (
      <div>
        <Menu>
          <Menu.Item
            name="Map"
            active={activePage === 'Map'}
            onClick={this.handleMenuClick}
          />
          <Menu.Item
            name="Dashboard"
            active={activePage === 'Dashboard'}
            onClick={this.handleMenuClick}
          />
          <Menu.Item
            name="Team"
            active={activePage === 'Team'}
            onClick={this.handleMenuClick}
          />

        </Menu>


        <Segment className={MapClass}>
          <Map />
        </Segment>

    {/* ................. Similarly for other tabs................... */}
      </div>
    );
  }

}

export default MainTabs;

CSS

.hidden {
  visibility: hidden;
}

Read more comments on GitHub >

github_iconTop Results From Across the Web

react semantic ui, how to rerender component when switching ...
I'm passing props to a component and I need to update it. Any ideas? const panes = [ { menuItem: "In process", render:...
Read more >
Prevent component to re-render when switching between ...
The component re-renders because when there is switch between tabs, the tab unmount it's panel & mount the next tab's panel.. so by...
Read more >
TabPanel in a React app - Editor losеs the a value after a ...
I tested using basic React component, re-render parent or changing child's props will not cause that 2 issues (loss focus, loss local state ......
Read more >
Why React Re-Renders - Josh W Comeau
React's “main job” is to keep the application UI in sync with the React state. The point of a re-render is to figure...
Read more >
react state change not rendering child component - You.com
React Child Component Not Updating After Parent State Change ... Open side panel ... activeTab}); } render() { return ( <ul className="nav nav-tabs"> ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found