TransWikia.com

Loop through a new json object every X seconds

Stack Overflow Asked by UnluckyLAD on November 19, 2020

I am trying to make a timer or interval. So that a new data is being shown on the screen every X seconds. I currently have an array of objects, and I want to show one object at the time, and data refreshing every X seconds.

this is my json:

{
    "exampleData": [
        {
            "id": 1,
            "title": "fun film",
            "genre": "comedy"
        },
        {
            "id": 2,
            "title": "not so fun film",
            "genre": "horror"
        }
    ]
}

this is my little map function:

 const renderExample= data.exampleData.map(function (data, idx) {
      return (
         <h2 key={idx}>
            {data.title}
            {data.genre}
         </h2>
      )
   });

So when the component is rendered I want the first object to be shown: title: fun film and genre comedy then after X seconds I would like the other object to be shown not so fun film, genre horror

I was thinking about using a useEffect with a setTimout but I’m not too sure where to start. Any tips?

2 Answers

You could just increase the index every X seconds and use the modulo operator to keep it looping. (Untested example below.)

const Your_Component = () => {
  const [current, setCurrent] = useState(0);
  const [data, setData] = useState(null);

  useEffect(() => {
    const intervalID = setInterval(() => {
      setCurrent((current) => (current + 1) % data.length);
    }, 5000) // 5 seconds

    return () => clearInterval(intervalID);
  }, []);

  return (
    <h2>
      {data[current].title}
      {data[current].genre}
    </h2>
  )
}

Correct answer by Reyno on November 19, 2020

Here's how I would do it. Same general concept as others, with a working example.

The main difference is that this uses the function form of setActive which prevents closures from being an issue in this case.

const { useState, useEffect } = React;
const data = {
  exampleData: [
    {
      id: 1,
      title: 'fun film',
      genre: 'comedy',
    },
    {
      id: 2,
      title: 'not so fun film',
      genre: 'horror',
    },
  ],
};
function Example() {
  const [active, setActive] = useState(0);
  useEffect(() => {
    // create an interval
    const intervalId = setInterval(() => {
      // increment and modulo the active state so it never goes out of bounds.
      // Set the new active using the function form of setActive so the closure doesn't matter
      setActive((active) => (active + 1) % data.exampleData.length);
    }, 1000);
    // Clean up the effect
    return () => clearInterval(intervalId);
  }, []);
  const currentData = data.exampleData[active];

  return (
    <h2>
      {currentData.title}
      {currentData.genre}
    </h2>
  );
}

ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"/>

Answered by Zachary Haber on November 19, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP