Reputation: 160
I have created tabs that are created by clicking on a menu item. After that I wanted the closing "X" to only appear when hovering over the <li>
parent.
I think it's a map problem that has not yet been created when I try to paint the "X" hover, but I do not know how to fix it. Why do I get this error? Can not update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.
class LiTabs extends Component{
constructor(props, context){
super(props, context);
["showCloseTabs",].forEach((method) => {
this[method] = this[method].bind(this);
});
this.state = {
closeTabs: false,
};
}
showCloseTabs(e){
this.setState({
closeTabs : true,
})
console.log(e);
}
render(){
return(
<>
{this.props.tabsLi.map((value, index) =>
<li key={index} onMouseOver={this.showCloseTabs(this)}>
<span>{value}</span>
<div onClick={this.props.removeTab.bind(this, value, index)} >
{this.state.closeTabs === true && (
<Icon icon="cerrar" className='ico-cerrar'/>
)}
</div>
</li>
)}
</>
);
}
}
Upvotes: 1
Views: 94
Reputation: 12806
You are missing a bind on this.showCloseTabs(this)
which causes it to call it directly
To be fair, you should probably just remove the (this)
all together there though (so even not have the bind in the mapping function)
{this.props.tabsLi.map((value, index) =>
<li key={index} onMouseOver={this.showCloseTabs.bind(this)}>
<span>{value}</span>
<div onClick={this.props.removeTab.bind(this, value, index)} >
{this.state.closeTabs === true && (
<Icon icon="cerrar" className='ico-cerrar'/>
)}
</div>
</li>
)}
To use class properties, you can change the declaration of your method like
showCloseTabs = (e) => { /* ... */ }
In both cases, you could then change the onMouseOver
property to be
onMouseOver={this.showCloseTabs}
And be done with it :)
Upvotes: 2
Reputation: 19224
this.showCloseTabs(this)
is a function call in JavaScript, this means that function is called when render
method is called.
This function is doing a setState
which leads to the error:
Can not update during an existing state transition (such as within
render
). Render methods should be a pure function of props and state.
What needs to be passed to onMouseOver
or onClick
are references to the functions. In case of showCloseTabs
, that is going to be:
onMouseOver={this.showCloseTabs}
If you need to pass arguments:
onMouseOver={(e) => this.showCloseTabs(e)}
Also binding the method in render
creates new functions very time render is called. Instead you can bind it in the constructor:
constructor() {
this.onMouseOver = this.onMouseOver.bind(this);
}
Upvotes: 2