Можно ли получить текущую длину массива, хранящегося в состоянии внутри интервала, запущенного в ловушке useEffect? - PullRequest
2 голосов
/ 25 апреля 2019

У меня есть ситуация, когда мне нужно вывести определенное количество элементов на действия пользователя (скажем, щелчок), каждый элемент должен появляться через 500 мс после предыдущего элемента. Массив элементов хранится внутри состояния, новые элементы добавляются внутри setInterval, работающего внутри ловушки useEffect.

Вот проблема: внутри ловушки и интервала у меня нет доступа к длине массива, и она не может быть передана как зависимость, так как это приведет к бесконечному циклу. Но я должен остановить интервал после того, как определенное количество элементов уже отображается.

Я нашел решение проблемы, сохранив итерацию setInterval в хуке. Интересно, правильно ли это или есть лучший / более идиоматический подход.

Я создал простой пример проблемы с кодами и окном: https://codesandbox.io/s/xo879wn08z

Ответы [ 2 ]

2 голосов
/ 25 апреля 2019

Вы можете очистить интервал в обратном вызове средства обновления состояний, когда у вас будет доступ к массиву номеров

setNumbers(numbers => {
    if (numbers.length === 9) {
      clearInterval(interval);
    }

    return [...numbers, Math.random()]
 });

Рабочая демонстрация

0 голосов
/ 25 апреля 2019

Как насчет того, чтобы вместо использования setInterval вы использовали setTimeout. Вы будете каждый раз создавать новый тайм-аут, но только если его длина меньше 10.

  useEffect(() => {
    let id;
    if (isCounting && numbers.length < 10) {
      id = setTimeout(() => setNumbers([...numbers, Math.random()]), 500);
    }
    return () => clearTimeout(id);
  }, [isCounting, numbers]);
...