0

I'm trying to get the largePlayer in state to automatically change its values every 2 seconds, so I'm trying to use setTimeout to loop through the mediaRoll array (also in state), but I keep getting the error that "setState is not a function"

`import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';
import Items from './Items.jsx';
import LargePlayer from './LargePlayer.jsx';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      largePlayer: "https://res.cloudinary.com/dq3iywusm/image/upload/w_600,h_337/1471163293-814525206_acfute.jpg",
      mediaRoll: []
    }
    this.rotateMedia = this.rotateMedia.bind(this)
  }
  componentDidMount() {
    this.loadMedia()
    this.rotateMedia()
  }

  loadMedia() {
    $.ajax({
      method: 'GET',
      url: '/media/items',
      success: (data) => {
        // console.log(data)
        this.setState({
          mediaRoll: JSON.parse(data)
        })
        this.rotateMedia()
      },
      error: (err) => {
        console.log('error with ajax loadMedia: ', err)
      }
    })
  }


  rotateMedia() {
    var array = this.state.mediaRoll
    var interval = 2000;
    array.forEach(function (el, index) {
      setTimeout(function () {
        this.setState({
          largePlayer: el.url
        })
        console.log(el.url);
      }, index * interval);
    });
  }

  render() {
    return (
      <div >
        <h1>Photo Carousel</h1>
        <LargePlayer largePlayer={this.state.largePlayer} />
        <Items mediaRoll={this.state.mediaRoll} />
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'));`

The ajax portion and everything works perfectly with the videos and pictures rendering, but I can't get that largePlayer in state to change every two seconds.

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
WDHud
  • 123
  • 11
  • Try using arrow functions for the `callback` functions inside `rotateMedia`. currently your using regular functions so the `this` keyword doesn't refer to the current class, it refers to the `callback` function – Hassan Azzam Jul 04 '20 at 21:00
  • Does this answer your question? [Are 'Arrow Functions' and 'Functions' equivalent / exchangeable?](https://stackoverflow.com/questions/34361379/are-arrow-functions-and-functions-equivalent-exchangeable) – Patrick Roberts Jul 04 '20 at 21:00
  • @HassanAzzam `this` doesn't refer to the callback function, it will be `undefined` in strict mode, or `window` otherwise. – Patrick Roberts Jul 04 '20 at 21:02
  • You basically only call `rotateMedia` once when the component mounts/loads data, and you also set the same timeout on ***all*** elements in the array at the same time so you queue up a bunch of state updates when the timeouts expire, so only the last timeout to expire and set state is the one that actually sets `largePlayer`. I think you should instead try using an interval that simply increments an index to use a specific url. – Drew Reese Jul 04 '20 at 21:27

0 Answers0