Reputation: 179
It's just a simple toggle mechanism:
Onclick of the element is to toggle a border color change by responding to state change. It changes the color once! But won't toggle back to original color.
(I've experimented with so many variations of the functionality, read/reread React docs on state, setState's asynchronous/batch change functionality, and combed SO again-and-again.)
Can someone help me find a solution?
Thanks in advance!
import React, { Component } from 'react';
class Button extends Component {
constructor(props) {
super(props);
this.state = {
active: false,
}
this.updateActive = this.updateActive.bind(this);
}
updateActive(){
this.setState(function(){
this.state.active = !this.state.active;
{ return this.state.active; }
});
}
render(){
return (
<div className="seq_btn" onClick={this.updateActive} style={ {borderColor: this.state.active ? 'black' : 'rgb(193, 255, 112)' }}></div>
)
}
}
export default Button;
Upvotes: 0
Views: 608
Reputation: 927
As a matter of good habit, you should never mutate state in any form that isn't directly performed with setState
Even using
this.state.active = !this.state.active
is bad form and is most likely your issue.
Instead consider
this.setState({ active: !this.state.active });
Also understand that setState's can be batched for processing later, they are not always immediately executed.
setState() does not always immediately update the component. It may batch or defer the update until later.
https://reactjs.org/docs/react-component.html#setstate
As noted below, a functional component would serve the same purpose without the overhead of lifecycle methods
import React from "react";
const Button = ({ active, clickAction }) => (
<div onClick={clickAction} className={{ borderColor: active ? "green": "purple"}}>
</div>);
export default Button;
Upvotes: 0
Reputation: 32076
Because your return syntax is incorrect:
this.setState(function(){
this.state.active = !this.state.active;
{ return this.state.active; }
});
This should be:
this.setState(function(){
return { active: !this.state.active };
});
However, you don't need to use the callback here at all. You should just setState with the new data.
this.setState({ active: !this.state.active });
Upvotes: 1