2

I have the following form which I would like to have a dynamic number of player name input fields, passed to PlayerSelect as props.numPlayers, and would like it to read the user input from each of those fields and pass the names as an array to this.props.setPlayers, which is a callback passed from the parent component.

I am trying to find the right way to access the PlayerNameInput components from the parent, as following doesn't seem to be working:

var PlayerSelect = React.createClass({
  getPlayers: function() {
    var playerNames = []
    for (var i = 0; i < this.players.length; i++) {
      var playerName = this.players[i].getDOMNode().value.trim();
      playerNames.push(playerName);
    }
    this.props.setPlayers(playerNames);
  },
  render: function() {
    this.players = []
    for (var i = 0; i < this.props.numPlayers; i++) {
      this.players.push(<PlayerNameInput />);
    }
    return (
      <div className="page">
        <form className="player-select">
          <ol className="players">
            {this.players}
          </ol>
          <button onClick={this.getPlayers}>Done</button>
        </form>
      </div>
    );
  }
});

var PlayerNameInput = React.createClass({
  render: function() {
    return (
      <li><input type="text"/></li>
    );
  }
});
0

1 Answer 1

4

You can use ref to access DOM node:

var PlayerSelect = React.createClass({
  getInitialState: function() { return { names: [] } },
  getPlayers: function(event) {
    event.preventDefault();
    var playerNames = []
    for (var i = 0; i < this.props.numPlayers; i++) {
      var playerName = this.refs['player-' + i].getDOMNode().value.trim();
      playerNames.push(playerName);
    }
    this.setState({ names: playerNames });
  },
  render: function() {
    var players = []
    for (var i = 0; i < this.props.numPlayers; i++) {
      players.push(
          <li key={'player-' + i}>
              <input ref={ 'player-' + i } type="text"/>
          </li>
      );
    }
    return (
      <div className="page">
        <form className="player-select">
          <ol className="players">
            {players}
          </ol>
          <button onClick={this.getPlayers}>Done</button>
        </form>
        <div>{ this.state.names.join(', ') }</div>
      </div>
    );
  }
});

JSFiddle

Also remember:

  • when you create array of elements every single one has to have unique key
  • don't modify props of your component to communicate with outside modules. Use some other library which provides models to communicate between components, for example Backbone or Flux ( in my example for simplicity I just saved collected player names to components state ).
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.