maths
maths

Reputation: 1429

Hide menu and redirect when clicking on react-router Link

For the menu of my site I am using links. When clicked on menu hamburger icon a hover over menu appears which is a checkbox. Now I want to hide the menu after i click a Link and go to another page. But the menu doesnt close, the page behind the menu changes which is good. I setup a function which changes the checkbox state to false but it doesn't hide the menu when a Link is clicked.

constructor(props) {
  super(props);
  this.state = {
    hamburger: false
  };
  this.turnOff= this.turnOff.bind(this);
}

turnOff = (e) => {
    this.setState({hamburger:false});
}

in render() i have:

<input name="hamburger" type="checkbox" id="menuToggle" onChange={this.handleChange} checked={this.state.hamburger} className="menu-toggle-input"></input>
<Link to="/about" onClick={this.turnOff}>About</Link>

When i click on link it loads the page on the background but the menu does not close and i get an error in console:

Can't perform a React state update on an unmounted component.

Upvotes: 3

Views: 3724

Answers (1)

ravibagul91
ravibagul91

Reputation: 20755

The issue is this,

<Link to="/about" onClick={this.turnOff}>About</Link>

When you click on Link, it will not wait till any associated click handler executes, in your case onClick={this.turnOff}. It will directly navigates to component with path /about and your component unmounts. After component unmounts, your turnOff function tries to change state which is not possible.

Instead of Link you can have simple button (styled as link),

<button onClick={this.turnOff}>About</button> 

You can make use of Redirect from react-router-dom package, in callback of setState.

Your function should be,

turnOff = (e) => {
    this.setState({hamburger:false}, () => <Redirect to="/about" />);
}

Update

You can make use of history object,

turnOff = (e) => {
    this.setState({hamburger:false}, () => this.props.history.push('/about'));
}

You need to import withRouter from react-router-dom and wrap your component with same.

import { withRouter } from 'react-router-dom';


export default withRouter(Your_Component_name)

Upvotes: 3

Related Questions