JavaScript React Basics (retired) Designing Data Flow Communicating Events

Zhiqiang Zhang
seal-mask
.a{fill-rule:evenodd;}techdegree
Zhiqiang Zhang
iOS Development Techdegree Student 10,679 Points

how it know which index is

return (
    <div className="counter">
      <button className="counter-action decrement" onClick={function() {props.onChange(-1);}} > - </button>
      <div className="counter-score"> {props.score} </div>
      <button className="counter-action increment" onClick={function() {props.onChange(1);}}> + </button>
    </div>
  );
}

here only pass the data to update not index

 return (
              <Player 
                onScoreChange={function(delta) {this.onScoreChange(index ,delta)}.bind(this)}
                onRemove={function() {this.onRemovePlayer(index)}.bind(this)}
                name={player.name} 
                score={player.score} 
                key={player.id} />
            );

how they know which index data to update in this return

4 Answers

The <Player> components are returned from an Array.map function on the players array, and its callback comes with three parameter: player, index and the array. The last one is not used.

<div className="players">
          {this.state.players.map(function(player, index) {
            return (
              <Player 
                name={player.name} 
                score={player.score} 
                key={player.id} 
                onScoreChange={
                  function(delta){this.onScoreChange(index, delta)}.bind(this)
                }
             />
          )
        }.bind(this))}
 </div>

Array.prototype.map()

we know map, but when the counter use the function it doesn't send the index.

The index parameter comes from the map function, and is being passed as the first argument when calling the Application component's onScoreChange method. The other parameter delta is being passed along with the callback functions on the Counter and Player components.

So, the click event handler is attached to the button elements in an instance of the Counter component (one Counter per Player). When those buttons are clicked, they trigger a function which executes the onChange function (from its props), and passes the delta argument of either -1 or 1 for decrement and increment respectively. That function triggers the onScoreChange function that is in the props of that Counter's parent instance of the Player component, which triggers the function that executes the onScoreChange function on the Application component, still passing the delta as an argument.

I don't know if this makes any more sense or just complicates things. I tried to find a diagram that explains how this works but couldn't find one... But basically props pass data down from parents to children, callbacks fire on children to trigger functions on parents.

akak
akak
29,441 Points

I currently have no access to the lessons so I can't see the full code (and from the code snippet you posted is difficult to assume for sure), but is the <Player> component returned from a loop or map function? It's common in react that you map over an array, return a component and index is the index of an item in array. So when using (like here) onClick method we know exactly which item it is.

The answer is because the Application makes a wrapper of the function. Making appear like function(delta) but inside it is function(index,delta), and the application controls the index.