Reputation: 13
I'm getting this warning:
Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to
this.state
directly or define astate = {};
class property with the desired state in the Navbar component.
I created a Navbar component with a NavMin component that only renders when the screen has a width of 11000 or less. I think it has something to do with using componentDidMount and componentWillUnmount but I am not sure how to properly use it. I have tried using componentWillUnmount in NavMin but I receive this error:
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
Here are the two components:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import bars from './Images/bars.png';
import './NavMini.css'
class NavMini extends Component {
componentWillUnmount(){
}
constructor(props){
super(props)
this.state = {
showMenu: false
}
this.showMenu = this.showMenu.bind(this)
this.closeMenu = this.closeMenu.bind(this)
}
showMenu(event){
event.preventDefault();
this.setState({
showMenu: true
},
() => {
document.addEventListener('click', this.closeMenu);
});
}
closeMenu(){
this.setState({
showMenu: false
}, () => {
document.removeEventListener('click', this.closeMenu);
})
}
render(){
return(
<div id="Navigation-mini">
<button onClick={this.showMenu} className="button-nav">
<img className="Mini-nav" src={bars} alt="nav-icon"/>
</button>
{
this.state.showMenu
? (
<div className="Navmenu">
<Link className="NavLink-mini" to='/'>Home</Link>
<Link className="NavLink-mini" to='/About'>About</Link>
<Link className="NavLink-mini" to='/Blog'>Blog</Link>
<Link className="NavLink-mini" to='/Contact'>Contact</Link>
</div>
)
: (
null
)
}
</div>
)
}
}
export default NavMini
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import Search from './Images/Search.png';
import Logo from './Images/Icon.png';
import NavMini from './NavMini'
import './NavBar.css';
class Navbar extends Component{
constructor(props){
super(props)
let width = window.innerWidth;
this.state = {
show: false
}
if(width < 1100){
this.setState({
show: true
})
}
}
render(){
return (
<div>
<div id="Navigation">
<div id="NavLogo">
<Link to='/'><img id="CodeDestinee" src={Logo} alt="Logo" /></Link>
<h3 id="LogoName">Code <br/> Destinee</h3>
</div>
<div id="Navbar">
<Link className="NavLink" to='/'>Home</Link>
<Link className="NavLink" to='/About'>About</Link>
<Link className="NavLink" to='/Blog'>Blog</Link>
<Link className="NavLink" to='/Contact'>Contact</Link>
<img className="NavLink" id="SearchIcon" src={Search} alt="Search-Icon" />
</div>
</div>
{ !this.state.show ? <NavMini /> : null }
</div>
)
}
}
export default Navbar
Can someone help me understand what I am doing wrong?
Upvotes: 1
Views: 642
Reputation: 704
componentDidMount() {
let width = window.innerWidth;
if(width < 1100){
this.setState({
show: true
})
}
}
Constructor is the only place where you should assign this.state
directly. In all other methods, you need to use this.setState()
instead.
Upvotes: 0
Reputation: 1782
As pointed out above, you're calling setState in the constructor which you shouldn't be doing. The above solution may work, but I believe a better solution is to set show
to true or false in one expression, depending on the width:
this.state = {
show: width < 1100
}
This will set this.state.show
to true or false, depending on the width.
Upvotes: 0
Reputation: 10997
You are using this.setState in constructor, please change it to
if(width < 1100){
this.state = {
show: true
}
}
Upvotes: 2