Apparently, I am trying to solve the same issue that this person had 12 years ago which hasn’t been solved. In the meantime, the referenced docs have changed of course, so I am asking the same question again.
I have the following setup: there are two tabs on the top level, the calculation tab and the results tab. The results tab contains tabs on a secondary level which display one calculation result each. On the calculation tab I can trigger an expensive calculation in the backend. When it returns, it opens a new tab on the secondary level in the results tab.
If I switch to the results tab while the calculation is running, everything is fine. However, if I am still on the calculation tab when the calculation finishes, a new tab is opened within the (currently hidden) results tab. In that case the following error is printed to the console, although the tab with this value definitely exists.
The `value` provided to the Tabs component is invalid.
The Tab with this `value` ("0") is not part of the document layout.
Make sure the tab item is present in the document or that it's not `display: none`.
Since it only occurs when the results tab is hidden, I would assume that MUI has a problem with updating hidden tabs. It seems to work fine, but I’d like MUI to not throw this error. Is there a way to do this or is my tab logic maybe flawed? My code :
import React, { Component } from 'react';
import { TabPanel } from './TabPanel';
import { Box, Tabs, Tab } from '@mui/material';
export class TabContainer extends Component {
constructor(props) {
super(props);
this.state = { selectedTabIndex: null }; // tab keys don't start at a predefined value, hence null
}
render() {
if (this.props.tabs.length === 0)
return;
let selectedTabIndex = this.state.selectedTabIndex; // if null get the key of the first tab
if (selectedTabIndex == null)
selectedTabIndex = this.props.tabs[0].key;
return (
<Box style={this.props.style}>
<Tabs value={selectedTabIndex} onChange={this.tabChange}>
{this.props.tabs.map((tab, index) =>
<Tab label={tab.label} value={tab.key} key={tab.key} />
)}
</Tabs>
{this.props.tabs.map((tab, index) => (
<TabPanel label={tab.label} hidden={selectedTabIndex !== tab.key} key={tab.key}>
{tab.content}
</TabPanel>
))}
</Box>
);
}
tabChange = (event, newValue) => {
this.setState({ selectedTabIndex: newValue }); // set to key of clicked tab
}
}
TabPanel:
import React, { Component } from 'react';
import { Box } from '@mui/material';
export class TabPanel extends Component {
render() {
return (
<div role="tabpanel" hidden={this.props.hidden}>
<Box sx={{ p: 3 }}>
{this.props.children}
</Box>
</div>
);
}
}