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?
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP