1

I have an array in React JS containing string data, I want to loop through that array and render each element of the array with some delay. I have tried setTimeout, setInterval but none of these work for me.

Instead, what I did I shifted that array into another array and put it in setTimeout so it might take some time but it didn't work for me

Here is the code

const [index, setIndex] = useState(0);
const [shiftArr, setShiftArr] = useState([]);
const fruitsArray = [
    "Apple",
    "Banana",
    "Mango",
    "Grapes",
    "Peach",
    "Avocado",
    "watermelon",
    "Pineapple",
    "Orange",
    "Strawbries",
  ];

useEffect(() => {
      
    for (let i = 0; i < fruitsArray.length; i++) {
      setTimeout(() => {
        setShiftArr((shiftArr) => [...shiftArr, fruitsArray[i]]);
        setIndex(i + 1);
      }, 2000);
    }
  }, []);

Rendering shifted array

<div className="fruitList">
          {shiftArr.map((fruit, ind) => (
            <div style={{ marginLeft: "20px" }} key={ind}>
              {fruit}
            </div>
          ))}
        </div>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
Sayyam abbasi
  • 109
  • 1
  • 8
  • 1
    Does this answer your question? [How to render one element at a time of a list, in a periodic manner, using react js?](https://stackoverflow.com/questions/58392604/how-to-render-one-element-at-a-time-of-a-list-in-a-periodic-manner-using-react) – Aniket Kariya Oct 20 '20 at 14:58
  • yes does any of the solution work? – Sayyam abbasi Oct 20 '20 at 15:01

1 Answers1

2

When you set the state, the Component is rerendered, and useEffect is called again if the dependencies change.

Use shiftArr as the dependency of useEffect, and if it's length is not identical to the original array, set the timeout, and create the shiftArray from the original array by slicing it to include the next item:

const { useState, useEffect } = React;

const Demo = ({ array }) => {
  const [shiftArr, setShiftArr] = useState([]);
  
  // initialize the shiftArr when array changes
  useEffect(() => setShiftArr(array.slice(0, 1)), [array]);
  
  useEffect(() => {
    if(shiftArr.length === array.length) return;
    
    const timeout = setTimeout(() => 
      setShiftArr(array.slice(0, shiftArr.length + 1))
    , 2000);
    
    return () => clearTimeout(timeout);
  }, [shiftArr]);

  return (
    <div className="fruitList">
      {shiftArr.map((fruit, ind) => (
        <div style={{ marginLeft: "20px" }} key={ind}>
          {fruit}
        </div>
      ))}
    </div>
  );
};

const fruits = ["Apple","Banana","Mango","Grapes","Peach","Avocado","watermelon","Pineapple","Orange","Strawbries"];

ReactDOM.render(
  <Demo array={fruits} />,
  root
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209