Home > front end >  Function doesn't return correct state
Function doesn't return correct state

Time:11-02

I am trying to write a function to get a random color from an array COLORS. But, the problem is instead of returning only one color, it is returning too many colors, resulting in an infinite error. Resulting in which react throws Too many re-renders error. What's wrong with my code?

const COLORS = [
  "#FFAEBC",
  "#1ec891",
  "#ff725e",
  "#ffd05b",
  "#A0E7E5",
  "#5885AF",
];

const DisplaySubject = (props) => {

  const [randomColor, setRandomColor] = useState("");

  const generateRandomColor = (colors) => {
    let randColorIndex, randColor;
    for (let i = 0; i < colors.length; i  ) {
      randColorIndex = Math.floor(Math.random() * colors.length);
      randColor = colors[randColorIndex];
      return randColor;
    }
    console.log(randColor);
    setRandomColor(randColor);
  };

  generateRandomColor(COLORS);

  console.log("random color state :", randomColor);
  return (
    <div>
      Let's get started
    </div>
  );
};

export default DisplaySubject;

CodePudding user response:

First, fix your color generator function:

const generateRandomColor = (colors) => {
    const randColorIndex = Math.floor(Math.random() * colors.length);
    return colors[randColorIndex];
};

Then you can use it as the initial value for useState:

const DisplaySubject = (props) => {
    const [randomColor, setRandomColor] = useState(generateRandomColor(COLORS));
    return (
        <div style={{ backgroundColor: randomColor }}>
            Let's get started
        </div>
    );
};

The problem was to call setRandomColor inside the getRandomColor function, that caused an infinite render cycle.

CodePudding user response:

You don't need to iterate through the array to get a random element. Change your function like this:

  const generateRandomColor = (colors) => {
    let randColorIndex, randColor;
    randColorIndex = Math.floor(Math.random() * colors.length);
    randColor = colors[randColorIndex];
    console.log(randColor);
    setRandomColor(randColor);
    return randColor;
  };

And the function gets called every time the component rerenders. So call the function on an event like onClick or if you want to run the function only once when the component renders for the first time, use useEffect:

useEffect(() => generateRandomColor(COLORS), [])

CodePudding user response:

Every time your component mounts, the function generateRandomColor() is called and then it updates the state which causes a new render.

As an option, you can create a button and call this function with onClick event:

<button onClick={generateRandomColor(COLORS)}>generate a color</button>
  • Related