Я хочу создать массив непересекающихся случайных чисел

Я хочу создать массив непересекающихся случайных чисел длиной 20.

Однако при выполнении массив не является полным и иногда появляется сообщение об ошибке «Слишком много повторных рендеров».

import React, {useState, useEffect} from "react";

const Ques = () => {

  const [randArr, setRandArr]  = useState([]);
  const [randNum, setRandNum] = useState(0);
  let rand = Math.floor(Math.random() * (19-0));

  if (randArr.length !== 20 && randArr.includes(randNum) === true){
    rand = Math.floor(Math.random() * (19-0));
    setRandNum(rand)
  }

  useEffect(() =>{
    setRandNum(rand);
    setRandArr([...randArr, randNum]);
    console.info("randNum : ", randNum);
    console.info("randArr : ", randArr);  
  },[rand]);


  
  return (
    <div>
      <button>Start</button>
    </div>
  );
};
export default Ques;

Вы создаете новое случайное число каждый раз, когда вызывается функция, поэтому оно всегда отличается, и запускается useEffect. Внутри вашего useEffect вы изменяете состояние, которое снова вызывает функцию, и это вызывает бесконечный цикл, который React предотвращает, и приводит к ошибке.

kellys 19.03.2022 04:51
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
1
31
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

import React, { useState, useEffect } from "react";

const App = () => {
  const [random, setRandom] = useState([]);

  const getRandom = () => Math.floor(Math.random() * (19 - 0));

  useEffect(() => {
    const arr = [];

    for (let i = 0; i < 20; i++) {
      arr.push(getRandom());
    }
    setRandom(arr);
    console.info(arr);
  }, []);

  return (
    <div>
      <div>{random.join(",")}</div>
      <button>Start</button>
    </div>
  );
};
export default App;

Здравствуйте, спасибо за ответ на SO. Как правило, следует избегать ответов только на код, поэтому не могли бы вы добавить объяснение и необходимую информацию?

code 19.03.2022 05:08
Ответ принят как подходящий

Как было указано в комментариях, вы объявляете новое значение rand в каждом цикле рендеринга и используете его в качестве зависимости для хука useEffect, который затем также ставит в очередь обновление состояния и запускает повторный рендеринг... повторять до тошноты.

Вместо того, чтобы пытаться перебирать и заполнять массив «случайными» числами, «угадывая», были ли они уже выбраны, было бы лучше начать с массива [1..20] и «перетасовать» его.

Пример:

const res = Array.from({ length: 20 }, (_, i) => i + 1).sort(() => Math.random() - 0.5);
console.info(res.join(","));

Вы можете просто инициализировать свое состояние этим значением. Никаких петель и useEffect крючков не нужно.

const [randArr, setRandArr] = useState(
  Array.from({ length: 20 }, (_, i) => i + 1).sort(() => Math.random() - 0.5)
);

Другие вопросы по теме