themollusk
themollusk

Reputation: 440

Delay array map iteration in React

I have this array, that I want to iterate. I need to delay it by a couple of seconds before the next.

{this.props.things.map((thing, index) => {
   return (
     <div key={index}>{thing.content}</div>
     // Delay 1 second here
   )
})}

The initial state of this array is always more than one. For UI purposes I want them to load in one by one in to the DOM.

Upvotes: 4

Views: 4983

Answers (1)

lorefnon
lorefnon

Reputation: 13105

The render function of react is synchronous. Also javascript map is synchronous. So using timers is not the right solution here.

You can however, in your component state, keep track of items that have been rendered and update that state using javascript timers:

For an example implementation check out this fiddle:

React.createClass({

  getInitialState() {
    return {
      renderedThings: [],
      itemsRendered: 0
    }
  },

  render() {
    // Render only the items in the renderedThings array
    return (
      <div>{
        this.state.renderedThings.map((thing, index) => (
          <div key={index}>{thing.content}</div>
        ))
      }</div>
    )
  },

  componentDidMount() {
    this.scheduleNextUpdate()
  },

  scheduleNextUpdate() {
    this.timer = setTimeout(this.updateRenderedThings, 1000)
  },

  updateRenderedThings() {
    const itemsRendered = this.state.itemsRendered
    const updatedState = {
      renderedThings: this.state.renderedThings.concat(this.props.things[this.state.itemsRendered]),
      itemsRendered: itemsRendered+1
    }
    this.setState(updatedState)
    if (updatedState.itemsRendered < this.props.things.length) {
      this.scheduleNextUpdate()
    }
  },

  componentWillUnmount() {
    clearTimeout(this.timer)
  }

})

Upvotes: 6

Related Questions