Использование setTimeout для приостановки выполнения для добавления анимации

#javascript #reactjs #sorting #settimeout #visualizer

#javascript #reactjs #сортировка #settimeout #визуализатор

Вопрос:

Я новичок в react js и сталкиваюсь с трудностями при манипулировании элементами DOM внутри функций.
Я пытаюсь создать визуализатор сортировки с помощью react. Для этого у меня есть div, состоящий из массива, использующего функцию map:

 {array.map((value, index) => (
    <div>
        <div 
            className="bar" 
            key={index} 
            ref = {(value) => this.arrayRef[index] = value}
            style={{height: `${value}px`}}></div>
    </div>
))}
  

Как вы можете видеть, я создал ссылку, чтобы я мог анимировать переходы с помощью:

 this.arrayRef[i].style.backgroundColor = 'blue'
  

Теперь, когда я использую цикл for для обновления цвета всего массива, я получаю сообщение об ошибке «не удается прочитать стиль свойства undefined». Ранее я обращался к панелям div с помощью document.getElementsByClassName, но после прочтения нескольких статей, из того, что я понял на данный момент, лучше использовать ссылки, поскольку document.getElementsByClassName выдаст ошибку, если мы попытаемся получить доступ к DOM до создания элемента.

 # this is what i meant 
for(i=0;i<this.arrayRef.length;i  ){
    setTimeout(()=>{
        this.arrayRef[i].style.backgroundColor = 'red';
    }, 500)
}

  

Я думаю, что проблема может быть в setTimeout здесь, потому что, если я опущу часть setTimeout, цвет всего массива изменится по мере необходимости. Но я хочу как-то показать анимацию, поэтому я хочу, чтобы она немного приостановилась, прежде чем раскрасить каждый элемент всего массива, вместо того, чтобы просто менять цвет без каких-либо пауз. Для этого я подумал, что setTimeout будет лучшим вариантом, я попытался использовать async / await, но мне все еще не совсем удобно использовать promises. Есть предложения о том, что может пойти не так? Любая помощь очень ценится!

Ответ №1:

Если вы хотите выполнять это по очереди, вы должны увеличить таймер следующим образом:

 for(i=0;i<this.arrayRef.length;i  ){
  setTimeout(()=>{
     this.arrayRef[i].style.backgroundColor = 'red';
  }, 500 * i)
}
  

setTimeout является асинхронным, он не блокирует выполнение.

ВВЕРХ: Для сохранения актуальности i внутри setTimeout вы должны установить его в качестве аргумента:

 for(i=0;i< 10;i  ){
  setTimeout(i=>{
     console.log(i);
  }, 500 * i, i)
}  

В вашем коде все таймауты выполняются ПОСЛЕ завершения цикла, поэтому i содержит значение array.length:

 for(i=0;i< 10;i  ){
  setTimeout(()=>{
     console.log(i);
  }, 500 * i)
}  

Также вы можете использовать let для предотвращения потери счетчика:

 for(let i=0;i< 10;i  ){
  setTimeout(()=>{
     console.log(i);
  }, 500 * i)
}  

Комментарии:

1. время не является большой проблемой, когда я запускаю приложение, в тот момент, когда оно выполняет строку с this.arrayRef[i] … отображается сообщение об ошибке «Не удается установить стиль свойства undefined»

2. О, конечно, подождите, я отредактирую ответ.. ваш i является последним при выполнении setTimeout

3. насколько я понимаю выполнение этой программы, цикл for продолжает выполняться, но setTimeout внутри цикла for ожидает установленного нами времени, поэтому в конце, когда i увеличивается, setTimeout, вероятно, все еще выполняется для некоторого this.arrayRef[i].style.backgroundColor, но на этот раз он выдает ошибку, потому что нет элемента i 1. как вы думаете, это может быть так??