Reputation: 409
I am just trying to create a very simple app which I will enter a number and the computer will generate boxes with that number and change color of one box at a time randomly. the code works but I don't understand why it works, at the randomBlinking function I just need to have this.setState({}) or more strange, I could just but anything in the state to this.setState({}) and the code will work the same, it will change color of a random box every 1 second. I cut down I app to only the part that I don't understand, could someone please help me answer this question.
import React from 'react';
import CubeRender from '../therapeuticEffect/CubeRender';
import '../therapeuticEffect/style.css';
class TherapeuticEffect extends React.Component {
constructor(props) {
super(props)
this.state = {
cubeArray: [],
cubeNumber: 0,
cubeSize: 100,
}
this.blinking = null;
}
onNumberChange = (event) => {
this.setState({ [event.target.name]: event.target.value })
}
onFormSubmit = (event) => {
event.preventDefault();
clearInterval(this.blinking);
this.cubeArrayRender();
}
cubeArrayRender = () => {
let { cubeNumber } = this.state;
let cubes = parseInt(cubeNumber, 10);
let array = cubes ? Array(cubes).fill() : [];
let cubeArray = array.length === 0 ? [] : array.map((c) => (this.randomColor()));
this.setState({ cubeArray })
this.randomBlinking();
}
randomBlinking = () => {
this.blinking = setInterval(() => {
const array = this.state.cubeArray;
const randIndex = Math.floor(Math.random() * array.length);
array[randIndex] = this.randomColor();
//HOW COULD THIS WORK
this.setState({})
}, 500);
}
randomColor = () => {
let r = Math.floor(Math.random() * 256);
let g = Math.floor(Math.random() * 256);
let b = Math.floor(Math.random() * 256);
let color = `rgb(${r}, ${g}, ${b})`
return color;
}
render() {
const { cubeArray, cubeNumber, cubeSize } = this.state
return (
<div>
<form className='menu-bar' onSubmit={this.onFormSubmit}>
<div>
<label>cube number </label>
<input type='number' name='cubeNumber' value={cubeNumber} onChange={this.onNumberChange} />
</div>
</form>
<CubeRender
cubeArray={cubeArray}
cubeSize={cubeSize}
/>
</div>
)
}
}
Upvotes: 1
Views: 34
Reputation: 112787
You are mutating your state directly by writing array[randIndex] = this.randomColor()
. This alone, which is not recommended, will not re-render your component. When you then write this.setState({});
the component will re-render with the state that you just mutated.
You could instead create a copy of your cubeArray
array and overwrite a random index with a random color and update your state with that.
randomBlinking = () => {
this.blinking = setInterval(() => {
this.setState(previousState => {
const cubeArray = [...previousState.cubeArray];
const randIndex = Math.floor(Math.random() * cubeArray.length);
cubeArray[randIndex] = this.randomColor();
return { cubeArray };
});
}, 500);
};
Upvotes: 2