I am using React Js in my project and the Material UI Tabs component to navigate between 2 components.
When I go to Tab 2 or Tab 1 by clicking on it, my component renders and the route gets changed but the tab indicator does not get updated on the active tab.
I've already tried to update the state on the button click but it isn't working
class NavBars extends React.Component {
state = {
value: 0,
};
handleChange = (event, value) => {
this.setState({ value });
console.log(this);
};
navigateToTab2 = () => {
this.setState({ value: 1 });
console.log(this.state);
this.props.history.push('/tab2');
}
navigateToTab1 = (facility, event) => {
this.setState({ value: 0 });
console.log(this.state);
this.props.history.push('/tab1', {
facilityId: facility.facilityId,
facilityName: facility.facilityName,
});
}
render() {
const { classes } = this.props;
const { value } = this.state;
return (
<div className={classes.root}>
<Tabs
value={value}
onChange={this.handleChange}
classes={{ root: classes.tabsRoot, indicator: classes.tabsIndicator }}
>
<Tab
disableRipple
classes={{ root: classes.tabRoot, selected: classes.tabSelected }}
label="Tab 1"
onClick={this.navigateToTab1}
/>
<Tab
disableRipple
classes={{ root: classes.tabRoot, selected: classes.tabSelected }}
label="Tab 2"
onClick={this.navigateToTab2}
/>
</Tabs>
</div>
);
}
}
I expect that when I click on Tab1 it should go to Tab1 and render that component with Tab indicator be on Tab 1 and when I click on Tab 2 it should go to Tab 2 and render the Tab 2 component with tab indicator on tab 2
A couple things:
There's really no point in setting onClick
events for each Tab
, because everything you need to do can be done in the onChange
handler for Tabs
.
So, when onChange
is fired, you can set the selected tab value, then call this.props.history.push
. Make sure you are rendering your child components based on the tab that was selected.
If you want the route /tab2
to automatically select tab2, then youll need to check the current route in componentDidMount()
, then set state accordingly. So for instance, if route == '/tab2' then state.value == 2
Here's an example taken straight from Material-UI docs.
<div className={classes.root}>
<AppBar position="static">
<Tabs value={value} onChange={this.handleChange}>
<Tab label="Item One" />
<Tab label="Item Two" />
<Tab label="Item Three" />
</Tabs>
</AppBar>
{value === 0 && <TabContainer>Item One</TabContainer>}
{value === 1 && <TabContainer>Item Two</TabContainer>}
{value === 2 && <TabContainer>Item Three</TabContainer>}
</div>
Your component should end up looking something like this
class NavBars extends React {
state = {
value: 0,
};
handleChange = (event, value) => {
if (value == 0) {this.props.history.push('/tab1')}
if(value == 1) {this.props.history.push('/tab2')}
};
componentDidMount() {
if(this.props.location.pathname == '/tab1') {
this.setState({value: 0})
} else {
this.setState({value: 1})
}
}
render() {
const { classes } = this.props;
const { value } = this.state;
return (
<div className={classes.root}>
<Tabs
value={value}
onChange={this.handleChange}
classes={{ root: classes.tabsRoot, indicator: classes.tabsIndicator }}
>
<Tab
disableRipple
classes={{ root: classes.tabRoot, selected: classes.tabSelected }}
label="Tab 1"
/>
<Tab
disableRipple
classes={{ root: classes.tabRoot, selected: classes.tabSelected }}
label="Tab 2"
/>
</Tabs>
{value == 0 && <p>Here is tab 1 content</p>}
{value == 1 && <p>Here is tab 2 content</p>}
</div>
);
}
}