Reputation: 133
I have two components
I want to display username after login in header.
Below is code...
class Header extends Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false
};
}
isLoggedIn = () => {
var flag = localStorage.getItem('loggedUser') !== null;
this.setState({isLoggedIn : flag}); // this line gives error
return flag;
}
render() {
if(this.isLoggedIn() == true){
return(
<div>
<div className="header">
<div className="headerUser">Logged in as: {localStorage.getItem("loggedUser")}</div>
<img src={Logo} className="app-logo" alt="logo" width="145" height="55" />
</div>
</div>
);
} else {
return(
<div>
<div className="header">
<img src={Logo} className="app-logo" alt="logo" width="145" height="55" />
</div>
</div>
);
}
}
}
export default Header;
How to change state inside function as it does not allow me to use this keyword..?
Error :
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
Upvotes: 0
Views: 1511
Reputation: 34107
Your code has entered a render loop since setState is indirectly called from render()
. render()
is called after a setState
call
Load the required data in componentDidMount()
and set its value in state and check for the state value in render, and don't use multiple return
see the below code.
class Header extends Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false
};
}
componentDidMount() {
var flag = localStorage.getItem('loggedUser') !== null;
this.setState({isLoggedIn : flag});
}
render() {
return(
{ this.state.isLoggedIn ?
<div>
<div className="header">
<div className="headerUser">Logged in as: {localStorage.getItem("loggedUser")}</div>
<img src={Logo} className="app-logo" alt="logo" width="145" height="55" />
</div>
</div>
: <div>
<div className="header">
<img src={Logo} className="app-logo" alt="logo" width="145" height="55" />
</div>
</div>
})
}
}
export default Header;
return()
can be further optimized like this
return(
<div>
<div className="header">
{ this.state.isLoggedIn ?<div className="headerUser">Logged in as: {localStorage.getItem("loggedUser")}</div> : null }
<img src={Logo} className="app-logo" alt="logo" width="145" height="55" />
</div>
</div>
)
Upvotes: 1
Reputation: 391
Well Here is your answer...
class Header extends Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false
};
}
isLoggedIn = () => localStorage.getItem('loggedUser') !== null;
render() {
if(this.isLoggedIn()) {
return(
<LoggedIn onMount={() => this.setState({isLoggedIn: this.isLoggedIn()})} />
);
} else {
return(
<div>
<div className="header">
<img src={Logo} className="app-logo" alt="logo" width="145" height="55" />
</div>
</div>
);
}
}
}
export default Header;
class LoggedIn extends Component {
componentWillMount() {
this.props.onMount();
}
render() {
return (
<div>
<div className="header">
<div className="headerUser">Logged in as: {localStorage.getItem("loggedUser")}</div>
<img src={Logo} className="app-logo" alt="logo" width="145" height="55"/>
</div>
</div>
)
}
}
export default LoggedIn;
Upvotes: 0
Reputation: 867
You’re setting state in your isLoggedIn
method,, which triggers another render, which calls isLoggedIn
again, etc. You should just check the state object in render directly (this.state.isLoggedIn
), and you should set the state only at the beginning, or when your user’s state changes.
Upvotes: 0
Reputation: 3103
you're calling setState while rendering... try like
class Header extends Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false
};
}
isLoggedIn = () => {
var flag = localStorage.getItem('loggedUser') !== null;
// this.setState({isLoggedIn : flag}); // delete here
return flag;
}
render() {
if(this.isLoggedIn() == true){
return(
<div>
<div className="header">
<div className="headerUser">Logged in as: {localStorage.getItem("loggedUser")}</div>
<img src={Logo} className="app-logo" alt="logo" width="145" height="55" />
</div>
</div>
);
} else {
return(
<div>
<div className="header">
<img src={Logo} className="app-logo" alt="logo" width="145" height="55" />
</div>
</div>
);
}
}
}
export default Header;
Upvotes: 0