Reputation: 194
Im coding up a project in ReactJS. Ive got some divs that can be clicked by user. By default every div's background color should be set to green, but after the click it should become red (meaning that this specific div has been already clicked and further clicking on it won't make any difference). My idea for setting the CSS class is that inside className I've got a ternary if statement based on corresponding value from the array. The solution I've presented doesn't do anything, no errors are popping up. How can I achieve my goal?
Code:
var style = require('./board.css');
var React = require('react');
class board extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
fieldClicksArray: [
false, false, false,
false, false, false,
false, false, false
]
}
}
handleClick(index) {
if (this.state.fieldClicksArray[index] === false) {
this.state.fieldClicksArray[index] = true;
}
render () {
return (
<div className="parent">
<div className={this.state.fieldClicksArray[0] ? 'red' : 'green'} onClick={() => this.handleClick(0)}>1</div>
</div>//parent
)//return
}//render
}//class
export default board;
The CSS:
.red {
background-color: red;
}
.green {
background-color: green;
}
Upvotes: 3
Views: 3512
Reputation: 6223
class Board extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
fieldClicksArray: [
false, false, false,
false, false, false,
false, false, false
]
}
}
handleClick(index) {
if (this.state.fieldClicksArray[index] === false) {
var newArray = this.state.fieldClicksArray;
newArray[index] = true;
this.setState({
fieldClicksArray: newArray
})
}
}
render(){
return(
<div className="parent">
<div className={this.state.fieldClicksArray[0] ? 'red' : 'green'} onClick= {()=>this.handleClick(0)}>1</div>
</div>//parent
)//return
}//render
}//class
ReactDOM.render(<Board />, document.getElementById("app"))
.red {
background-color: red;
}
.green {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
this.state.fieldClicksArray[index] = true;
wont perform anything. you need to call this.setState
to change the state of your component.
handleClick(index) {
if (this.state.fieldClicksArray[index] === false) {
var newArray = this.state.fieldClicksArray;
newArray[index] === false;
this.setState({
fieldClicksArray: newArray
})
}
Also to use setState
method in your click handler, you'll need to bind your function to the component,
render () {
return (
<div className="parent">
<div className={this.state.fieldClicksArray[0] ? 'red' : 'green'} onClick= {()=>this.handleClick(0)}>1</div>
</div>//parent
)//return
}
Upvotes: 1
Reputation: 268225
You need to use setState()
. And clone the array so that you don't mutate the previous state. Finally, it is better to use the functional form of setState()
when your next state is calculated from previous state.
handleClick(index) {
this.setState((prevState) => {
// make a copy
let fieldClicksArray = prevState.fieldClicksArray.slice();
// change one item
fieldsClickArray[index] = true;
// return next state to be merged
return { fieldsClickArray };
});
}
Read more: https://facebook.github.io/react/docs/state-and-lifecycle.html#using-state-correctly
Hope this helps!
Upvotes: 4