13
votes

I'm trying to use Material UI Tabs for navigation. However, there are routes in my application that match none of the tabs. When I pass a value to the Tabs component that does not match any of the child tab values, I get a warning about an invalid value.

I created a hidden tab will a value of null as a work-around.

  1. Is it possible to disable this warning about an invalid tab value?
  2. Can tabs in Material UI have no selection?

Thanks

3

3 Answers

23
votes

The value of the currently selected Tab. If you don't want any selected Tab, you can set this property to false.

From: https://material-ui.com/api/tabs/

What I ended up doing is creating a switch statement with valid tab values, and if windows.location.pathname doesn't match any of them have the default return false.

Example Routes:

class Routes extends Component {
  render() {
    return (
      <Switch>
        <Route path={'/test2'} component={Test2} />
        <Route path={'/test3'} component={Test3} />
        <Route exact path={'/'} component={Test} />
      </Switch>
    );
  }
}

Example NavBar:

checkPathnameValue() {
  const { pathname } = window.location;
  switch (pathname) {
    case '/test2':
    case '/test3':
    break;
  default:
    return false;
  }
  return pathname;
}

render() {
  const { classes } = this.props;
  const tabValue = this.checkPathnameValue();
  return (
    <div className={classes.root}>
      <AppBar position={'static'}>
        <Toolbar>
          <Tabs value={tabValue}>
            <Tab
              label={'Test 2'}
              value={'/test2'}
              to={'/test2'}
              component={Link}
            />
            <Tab
              label={'Test 3'}
              value={'/test3'}
              to={'/test3'}
              component={Link}
            />
          </Tabs>
        </Toolbar>
      </AppBar>
    </div>
  );
}
8
votes

Seems like setting the value property of Tabs to false will not show any warning and will deselect all the tabs correctly.

Philip's solution works perfectly, here I am just removing the need for the switch case.

In my case, I only had one tab (Login) where I wanted no tab to be selected since it is a button rather than a tab.

Here's what I did to solve this:

<Tabs value={this.state.content !== "login" ? this.state.content : false} onChange={(event, newValue) => { this.setState({content: newValue}) }}>
  <Tab value="home" label="Home" wrapped />
  <Tab value="tab1" label="Tab 1" />
  <Tab value="tab2" label="Tab 2" />
</Tabs>

on another part of my AppBar I had a Login button:

<Button onClick={(event, newValue) => { this.setState({content: "login"}) }}>Login</Button >

Similarly to Philips's answer, the key is in {this.state.content !== "login" ? this.state.content : false} which prevents Tabs from being rendered with "login" value. Instead, it is given the value "false" which is allowed and does not invoke the warning.

0
votes

I also experienced this issue a while back and follow the same pattern. E.g.,

return <Tabbar value={value ?? false} onChange={(event: React.ChangeEvent<{}>, value: any) => onChange(value)}>{tabs}</Tabbar>