This is a color changer on react from pressing a button. But one issue it faces is that after a few clicks, it stops working. Can anyone help with this?
import './App.css';
import React, {useState} from 'react';
import Button from './components/Button'
function App() {
const [color, setColor] = useState("yellow")
const colorPalette = ['#FF6633', '#FFB399', '#FF33FF', '#FFFF99', '#00B3E6',
'#E6B333', '#3366E6', '#999966', '#99FF99', '#B34D4D',
'#80B300', '#809900', '#E6B3B3', '#6680B3', '#66991A',
'#FF99E6', '#CCFF1A', '#FF1A66', '#E6331A', '#33FFCC',
'#66994D', '#B366CC', '#4D8000', '#B33300', '#CC80CC',
'#66664D', '#991AFF', '#E666FF', '#4DB3FF', '#1AB399',
'#E666B3', '#33991A', '#CC9999', '#B3B31A', '#00E680',
'#4D8066', '#809980', '#E6FF80', '#1AFF33', '#999933',
'#FF3380', '#CCCC00', '#66E64D', '#4D80CC', '#9900B3',
'#E64D66', '#4DB380', '#FF4D4D', '#99E6E6', '#6666FF'];
let randomNum = Math.floor(Math.random() * 50)
return (
<div style = {{backgroundColor: color, height: 300}}>
<button onClick = {() => setColor(colorPalette[randomNum])}>Click me to change color!</button>
</div>
);
}
export default App;
CodePudding user response:
Problem
It will work until there's a collision. A collision occurs when the previous value in randomNum
is the same as a new one. This means the new value stored in color
state will be the same as its old state. When the state is unchanged, React won't re-render the component App
. Now, since the random number generation relies on the App
component being re-rendered, a new value for randomNum
won't be generated.
Helps to think like so: here the component is a function, every (re-)render is equivalent to calling that function. Now, if the function isn't called, randomNum
won't get a new value assigned to it. That in turn will not trigger a re-render.
Solution
Generate a new random value upon each click. Create a function to do that and call it upon every click of the button. Full working demo here. Code of interest below.
const genRandomNum = () => Math.floor(Math.random() * 50)
return (
...
<button onClick={() => setColor(colorPalette[genRandomNum()])}>
Click me to change color!
</button>
...)
CodePudding user response:
Instead of writing event handler inline ,create separate function for the event handler like below
const handleClick = () => {
let randomNum = Math.floor(Math.random() * 50);
setColor(colorPalette[randomNum]);
};
return (
<div style={{ backgroundColor: color, height: 300 }}>
<button onClick={handleClick}>Click me to change color!</button>
</div>
);
Why your code were not working because when number generator logic return the same number ,then re-render does not happens and because of that new number will not get generated
CodePudding user response:
you have 50 colours and a random number may return 60 and in return, it will pass undefined, first, you should set the range of your random colour between 0 and 49 to get correct color range
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) min); //The maximum is exclusive and the minimum is inclusive
}