0

I am trying to move the first item of an array to the last position of the array in React, using a setInterval function:

const [cardOrder, setCardOrder] = useState([card1, card2, card3, card4]);
setInterval(() => {
    setCardOrder(cards.push(cards.shift()))
}, 3000); 

The first time always works, but the second time I get

TypeError: cardsOrder.shift is not a function

How can I achieve this result? All help appreciated. Thanks.

Noah Gwynn
  • 256
  • 2
  • 12
  • You say "using a setTimout function" and then use `setInterval`, which is not the same as "setTimout" or `setTimeout`. Then you show code which does not use the variable `cardsOrder` but say you're getting an error about `cardsOrder.shift` no being a function. The mismatches between your question text and your code make it difficult to follow the question... Please show the actual code used and the errors produced by that code. – Heretic Monkey Oct 27 '20 at 18:22
  • Apologies, I rushed the question. setInterval was what I meant. – Noah Gwynn Oct 27 '20 at 18:46
  • You can always [edit] your question to make it the best it can be. – Heretic Monkey Oct 27 '20 at 18:48

3 Answers3

0

Few issues with your code, e.g. cardsOrder is not defined. Also you are missing some essential stuff, like state management and lifecycle aka hooks. Also not sure why do you need the i variable. Anyways, heres a possible, alternative solution:

const { useEffect, useState } = React;

const App = () => {
  const [arr, setFn] = useState(['first', 'second', 'third', 'fourth']);
  
  useEffect(() => {
     const i = setInterval(() => {
        setFn(([first, ...rest]) => [...rest, first]);
     }, 1000);
     
     return () => clearInterval(i);
  }, []);
  
  return arr.join('\n');
}

ReactDOM.render(<App />, document.getElementById("root"));
body {
   white-space: pre;
}
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
kind user
  • 40,029
  • 7
  • 67
  • 77
0

It's because, [].push() returns length of the array. So when you do setOrder(cards.push(cards.shift(i))) cards will be changed (Array) to Number(length of the Array), next time when you call this will become (number)1.shift which is not function. That's why you're getting that error.

Change your code to:

 setInterval(() => {
   cards.push(cards.shift())
   setOrder([...cards]) // this will work.

   // OR

   const card = cards.shift()
   setOrder([...cards, card])
 }, 3000)
Naren
  • 4,152
  • 3
  • 17
  • 28
0

You can implement swap as Array prototype

Array.prototype.swap = function (x, y) {
  var z = this[x];
  this[x] = this[y];
  this[y] = z;
  return this;
}

and then use it

const array= [{a:'a',b:'b'},{c:'c',d:'d'}];
const newArray = array.swap(0,1)

newArray if what are you looking for. Use insted .swap(0,3)

  • "You can implement swap as Array prototype" but don't, unless you have absolute control over all of the code used in your application and its dependencies. See [Why is extending native objects a bad practice?](https://stackoverflow.com/q/14034180/215552) – Heretic Monkey Oct 27 '20 at 18:25
  • So he can implement as a simple function. – Marcos Molina Oct 27 '20 at 18:45