Я хочу создать массив непересекающихся случайных чисел длиной 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;
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. Как правило, следует избегать ответов только на код, поэтому не могли бы вы добавить объяснение и необходимую информацию?
Как было указано в комментариях, вы объявляете новое значение 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)
);
Вы создаете новое случайное число каждый раз, когда вызывается функция, поэтому оно всегда отличается, и запускается useEffect. Внутри вашего useEffect вы изменяете состояние, которое снова вызывает функцию, и это вызывает бесконечный цикл, который React предотвращает, и приводит к ошибке.