Как бесконечный цикл через массив в фиксированное время и хранить обновленное значение вне цикла каждый раз? - PullRequest
0 голосов
/ 22 октября 2019

Я пытаюсь перебрать цвета радуги на бесконечное время с фиксированным интервалом и обновить этот цвет в браузере DOM.

Попытаться понять. Мы должны обновить newColor не только внутри, но и вне цикла.

import React from 'react'

const Rainbow = (WrapedComponent) =>{

        const colors = ['violet', 'indigo', 'blue', 'green', 'yellow', 'orange', 'red'];

        let i=0;
        let newColor;


        setInterval(() => {
            newColor = colors[i];
            if (i === (colors.length - 1)) {
                i = 0;
            } else {
                i++;
            }
        }, 500);


        let newStyle = {
            color: newColor
        }


    return (props) => {
        return (
            <div style={newStyle}>
                <h1>Hello World</h1>
                <WrapedComponent {...props}/>
            </div>
        )
    }
}

export default Rainbow

Ответы [ 4 ]

2 голосов
/ 22 октября 2019

Вместо того, чтобы создавать новую область и рекурсивно вызывать loopforver ... навсегда ... и каждый раз создавать новый setTimeout, просто используйте setInterval. Я также добавил newStyle.color в цикл, потому что иначе вы никогда ничего не устанавливаете. newstyle.color = newColor происходит только один раз, похоже, вы ожидаете, что он каким-то образом будет связан.

const colors = ['violet', 'indigo', 'blue', 'green', 'yellow',
  'orange', 'red'
];

let i = 0;
let newColor;
let newStyle = {};
let intervalId = window.setInterval(() => {
    newStyle.color = colors[i];
    //Apply newStyle to some dom element here if need be
    i++
    if (i === 6) {
        i = 0;
    }

}, 500);

//When you're ready to be done
window.clearInterval(intervalId);
1 голос
/ 22 октября 2019

Ваш вопрос был изначально помечен reactjs до того, как он был удален, потому что неясно, откуда вступает в реакцию реакция из вашего примера кода. Тем не менее, вы просто позвоните this.setState() вместо console.log(), чтобы обновить свойство color в состоянии вашего компонента.

И еще несколько моментов, на которые следует обратить внимание:

  1. Вместо того, чтобы вызывать функцию через setTimeout() снова и снова, используйте setInterval().
  2. Ваш код не достиг "red", потому что индекс был сброшен ранее. Я также изменил код, чтобы динамически учитывать длину массива без его жесткого кодирования.

const colors = ['violet', 'indigo', 'blue', 'green', 'yellow', 'orange', 'red'];

let i = 0;
let newColor;

setInterval(() => {
  newColor = colors[i];
  document.documentElement.style.backgroundColor = newColor;
  // this is where you would call
  // this.setState({color: newColor});
  if (i === (colors.length - 1)) {
    i = 0;
  } else {
    i++;
  }
}, 500);
1 голос
/ 22 октября 2019

Вы обновляете newColor просто отлично;проблема в том, что newStylenewStyle.color) назначается только один раз. Хотя newStyle.color изначально ссылается на первое значение из newColor, это не то же самое, что newStyle.color, постоянно ссылающийся на будущие значения newColor.

Просто измените newColor = colors[i] вваш тайм-аут на newStyle.color = colors[i] для обновления этого объекта. Если вы хотите, чтобы newStyle был применен к чему-то в DOM, вам, конечно, нужно убедиться, что код также находится на своем месте.

Редактировать:

Теперь, когда выяснилось, что это React, вам понадобятся некоторые изменения. React не собирается отслеживать локальные переменные на предмет изменений и применять их в DOM. Вместо этого вы должны специально запустить обновление в React. Самый простой способ сделать это через state . Изменения в состоянии вызывают повторную визуализацию. Вы также захотите превратить ваш интервал таймера в эффект , который можно отключить, когда компонент отключен.

import React from 'react'
const { useEffect, useState } = React;

const colors = ['violet', 'indigo', 'blue', 'green', 'yellow', 'orange', 'red'];

const Rainbow = (WrappedComponent) => {
  return (props) => {
    const [color, setColor] = useState(0);

    useEffect(() => {
      const timeout = setTimeout(() => {
        setColor((color + 1) % colors.length);
      }, 500);
      return () => clearTimeout(timeout);
    }, [color]);

    return (
      <div style={{ color: colors[color] }}>
        <h1>Hello World</h1>
        <WrappedComponent {...props}/>
      </div>
    );
  }
}

export default Rainbow
0 голосов
/ 22 октября 2019

метод setTimeout отключается на 500 мс и выполняется вечно, и к моменту выполнения setTimeout

    let newStyle = {
      color: newColor
    }

уже выполняется. Вот почему вы не можете получить новый цвет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...