TrafficLight с использованием SetTImeout и ReactHooks - PullRequest
0 голосов
/ 08 марта 2020
const lightDurations = [ 5000, 2000, 1000];

const TrafficLight = ({ initialValue }) => {
  const [colorIndex, setColorIndex] = useState(initialValue);

  useEffect(() => {
    const timer = setTimeout(() => {
      setColorIndex((colorIndex + 1) % 3);
    }, lightDurations[colorIndex]);
    return () => {
      clearTimeout(timer);
    };
  });

  return (
    <div className="traffic-light">
      <Light color="#f00" active={colorIndex === 0} />
      <Light color="#ff0" active={colorIndex === 2} />
      <Light color="#0c0" active={colorIndex === 1} />
    </div>
  );
};

Код работает отлично. Это всего лишь светильник traffi c, который меняет свой цвет. Но сначала мне нужно, чтобы три индикатора были активны в течение пяти секунд и только один раз. Я не знаю, как это сделать.

1 Ответ

1 голос
/ 08 марта 2020

Вы можете добавить дополнительную переменную состояния, которая представляет, работает ли TrafficLight или находится в исходном состоянии. Тогда вам просто нужно переключить это состояние так же, как вы делаете это для colorIndex.

const initialDelay = 5000;

const TrafficLight = ({ initialValue }) => {
  const [colorIndex, setColorIndex] = useState(initialValue);
  const [isStarted, setIsStarted] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => {
      setIsStarted(true);
    }, initialDelay);
    return () => {
      clearTimeout(timer);
    };
  }, []); // note [] - it makes it run once

  useEffect(() => {
    if (!isStarted) {
      return;
    }
    const timer = setTimeout(() => {
      setColorIndex((colorIndex + 1) % 3);
    }, lightDurations[colorIndex]);
    return () => {
      clearTimeout(timer);
    };
  });

  return (
    <div className="traffic-light">
      <Light color="#f00" active={!isStarted || colorIndex === 0} />
      <Light color="#ff0" active={!isStarted || colorIndex === 2} />
      <Light color="#0c0" active={!isStarted || colorIndex === 1} />
    </div>
  );
};
...