Ad

React JS Synchronous Handling Of Array.map

- 1 answer

I am very new to React JS and in some ways javascript here is the problem I am trying to solve. I have a function in a component that looks like the below that iterates through an array of numbers:

 playerSequence: function() {
        var game = this;
        this.state.game.sequence.map(function(currNum){
            console.log(currNum);
              switch(currNum){
                  case 1:
                      game.handleBlue();
                      break;
                  case 2:
                      game.handleYellow();
                      break;
                  case 3:
                      game.handleGreen();
                      break;
                  case 4:
                      game.handleRed();
                      break;

              }
          })
    },

Each function call has a setTimeout that waits a period of time and renders a light and then switches off the light after this.props.wait ms. Below is an example:

var RedOn = React.createClass({
    mixins: [TimerMixin],
    componentDidMount: function () {
        this.setTimeout(function(){this.props.handleRed()}, this.props.wait);
    },
    handleRed: function() {
        this.props.handleRed()
    },
renderstuff
});

What I would like is for each pass through the map array to wait until the function call is finished and then continue. As it is right now they all go off at the same time. I am sure I am not fully understanding the nature of node, react or a combo of both. Any help would be appreciated.

Ad

Answer

According to the React docs, componentDidMount is Invoked once, only on the client (not on the server), immediately after the initial rendering occurs.

So it would make sense that they would all fire at once. The other problem is that setTimeout is invoked as soon as its called, which means if you pass some time in milliseconds to each function, map will simply invoke them all at once, not apply them sequentially. If you wanted to keep using map, you should declare a variable to store previous time applied, and add it into each timeout.

var previousTime = 0; 

["foo", "bar", "baz"].map( function(e) { 
    setTimeout( function() { console.log(e); }, 1000 + previousTime); 
previousTime += 1000; });

Here's a trivial example of what I'm describing. Try running this in a console to see the result. Every time you call "setTimeout" you add the time to the previousTime variable, so that each element waits an additional second before showing.

At the end of the day, even with all the abstractions offered by React, remember It'sJustJavaScript™

Ad
source: stackoverflow.com
Ad