I have no clue why this.role is undefined in render.
export default class Dashboard extends Component {
ponentDidMount() {
this.role = window.localStorage.getItem('role')
console.log('role', this.role) //return admin
}
render(){
console.log('role', this.role) //return undefined
return(
<div>
Component
</div>
)
}
}
I checked the localStorage of my app and it has value.
I have no clue why this.role is undefined in render.
export default class Dashboard extends Component {
ponentDidMount() {
this.role = window.localStorage.getItem('role')
console.log('role', this.role) //return admin
}
render(){
console.log('role', this.role) //return undefined
return(
<div>
Component
</div>
)
}
}
I checked the localStorage of my app and it has value.
Share Improve this question asked Jan 8, 2018 at 13:51 Jenny MokJenny Mok 2,8049 gold badges33 silver badges62 bronze badges3 Answers
Reset to default 3what happens is that at the initial render, render() method is called (before ponentDidMount() is called), so it shows 'undefined'. changing the value of 'this.role' won't re-render the page.
You will have to use state for this. Below code should work I believe.
export default class Dashboard extends Component {
constructor(){
super()
this.state = {
role : undefined
}
}
ponentDidMount() {
this.setState({role: window.localStorage.getItem('role')})
console.log('role', this.role) //return admin
}
render(){
console.log('role', this.state.role) //return undefined
return(
<div>
Component
</div>
)
}
}
It's returning undefined because you're setting this.role
after the ponent is mount (ponentDidMount
). So the first render doesn't have this.role
.
After ponentDidMount
is run you're not changing the state and the render is not running again (and therefore not getting the new info).
Try with ponentWillMount
instead, it should probably work.
Here's the React Lifecycle documentation.
Edit: Added code.
export default class Dashboard extends Component {
ponentWillMount() {
this.role = window.localStorage.getItem('role')
console.log('role', this.role) // return admin
}
render(){
console.log('role', this.role) // now returning admin because this.role is set before the 1st render
return(
<div>
Component
</div>
)
}
}
As other users have pointed out, you can also use setState instead and it would also work (In that case, when the state changes the render is run again and your role is displayed accordingly).
You see undefined
in the view because by the time the ponent has rendered there was nothing in role
because ponentDidMount
is called after the initial render. Moreover, the ponent doesn't rerender after you have set role
value from localStorage
because it is not on the state. If you place role
on the state and do this:
ponentDidMount() {
this.setState({ role: window.localStorage.getItem('role')});
}
render(){
console.log('role', this.state.role)
return(
<div>
Component
</div>
)
}
then you will be able to see value of role
in the view, but it will cause extra rerender of the ponent since you will change its state
, according to react docs about ponentDidMount
:
Calling setState() in this method will trigger an extra rendering, but it will happen before the browser updates the screen.
You can read more about ponentDidMount
here.
Update:
In your case you don't have to put role
on the state, but then you can fetch its value from the constructor
:
constructor(props) {
super(props);
this.role = window.localStorage.getItem('role');
}
and it will be available in the view.