1

Desired outcome = change image and bg color every x seconds.

Problem I'm running into = it is not displaying every color and image. It is going from pink -> orange -> pink -> orange, skipping blue and green.

import * as React from 'react';

// Images
import heroPink from './hero-pink.png';
import heroBlue from './hero-blue.png';
import heroOrange from './hero-orange.png';
import heroGreen from './hero-green.png';
import logo from './oddballs_logo.svg';


const colors = [
  "#F9B199",
  "#237E95",
  "#D79446",
  "#C2C138"
];

const images = [
  heroPink,
  heroBlue,
  heroOrange,
  heroGreen
];

export default function App() {
  const [value, setValue] = React.useState(0);

  React.useEffect(() => {
    const interval = setInterval(() => {
      setValue((v) => (v === 3 ? 0 : v + 1));
    }, 1000);
  }, []);

  return (
    <div className="App" style={{ backgroundColor: colors[value] }}>
      <img src={images[value]}/>
    </div>

  );
}

2 Answers 2

4

You need to clear your interval with the return statement. That means, in every un-mount the interval will clear and when this component will mount, new interval will register. It works fine for me, hope your problem will solve also.

  React.useEffect(() => {
    const interval = setInterval(() => {
      setValue((v) => {
        return v === 4 ? 0 : v + 1;
      });
    }, 1000);
    return () => clearInterval(interval);
  }, []);

Remember, clearing any interval events is important. Otherwise it occurs memory leak.


Here is the full example:

import React from "react";

const colors = ["#92c952", "#771796", "#24f355", "#d32776", "#f66b97"];

const images = [
  "https://via.placeholder.com/150/92c952",
  "https://via.placeholder.com/150/771796",
  "https://via.placeholder.com/150/24f355",
  "https://via.placeholder.com/150/d32776",
  "https://via.placeholder.com/150/f66b97"
];

export default function App() {
  const [value, setValue] = React.useState(0);

  React.useEffect(() => {
    const interval = setInterval(() => {
      setValue((v) => {
        return v === 4 ? 0 : v + 1;
      });
    }, 1000);
    return () => clearInterval(interval);
  }, []);

  return (
    <div className="App" style={{ backgroundColor: colors[value] }}>
      <img src={images[value]} alt="img" style={{ border: "3px solid" }} />
    </div>
  );
}
Sign up to request clarification or add additional context in comments.

3 Comments

You can also simplify the state update by doing setValue((v) => (v + 1) % 4);
@PatrickRoberts yeh, I just need to console.log v :) updating my answer.
oh (v+1)%4 😎, excellent 🥇 @PatrickRoberts
1

You can use setInterval function to achieve the behavior. Here I have used two states for color and image indexes.

const colors = ["#eb4034", "#ebdb34", "#34eb37"];

const images = [
  "https://images.unsplash.com/photo-1649894158666-c10421960f13?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2071&q=50",
  "https://images.unsplash.com/photo-1648737154448-ccf0cafae1c2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80",
  "https://images.unsplash.com/photo-1585974738771-84483dd9f89f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1072&q=80"
];

export default function App() {
  const [image, setImage] = useState(0);
  const [color, setColor] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      if (image === images.length - 1 && color === colors.length - 1) {
        setImage(0);
        setColor(0);
      } else {
        setImage(image + 1);
        setColor(color + 1);
      }
    }, 3000);

    return () => {
      clearInterval(interval);
    };
  }, [image, color]);

  return (
    <div style={{ backgroundColor: `${colors[color]}`, padding: "20px" }}>
      <img src={images[image]} style={{ width: "100%" }} alt="img" />
    </div>
  );
}

Also cleanup the interval unmounting phase.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.