Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialAshi A
2,531 Pointscan't add new player to array players Cannot add new players - page refreshes and I lose the newly added player
var PLAYERS = [
{
name: "Jim Hoskins",
score: 31,
id: 1,
},
{
name: "Andrew Chalkley",
score: 35,
id: 2,
},
{
name: "Alena Holligan",
score: 42,
id: 3,
},
];
var nextId = 4;
var AddPlayerForm = React.createClass({
propTypes: {
onAdd: React.PropTypes.func.isRequired,
},
getInitialState: function() {
return {
name: "",
};
},
onNameChange: function(e) {
//console.log('onNameChange', e.target.value);
//update name to e.target.value
this.setState({name: e.target.value});
//every time i type update state - which will cause a re-render
},
onSubmit: function(e) {
e.preventDefault; //prevent from resubmitting to itself
//pass the name up to the application
this.props.onAdd(this.state.name);
//on submit, clear out name
this.setState({ name: "" });
},
render: function() {
return (
<div className="add-player-form">
<form onSubmit={this.onSubmit}>
<input type="text" value={this.state.name} onChange={this.onNameChange}/>
<input type="submit" value="Add Player" />
</form>
</div>
);
}
});
function Stats(props) {
var totalPlayers = props.players.length;
var totalPoints = props.players.reduce(function(total, player){
return total + player.score;
}, 0)
return (
<table className="stats">
<tbody>
<tr>
<td>
Players
</td>
<td>
{totalPlayers}
</td>
</tr>
<tr>
<td>
Total Points
</td>
<td>
{totalPoints}
</td>
</tr>
</tbody>
</table>
);
}
Stats.propTypes = {
players: React.PropTypes.array.isRequired,
};
function Header(props) {
return (
<div className="header">
<Stats players={props.players} />
<h1>{props.title}</h1>
</div>
);
}
Header.propTypes = {
title: React.PropTypes.string.isRequired,
players: React.PropTypes.array.isRequired,
};
function Counter (props) {
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>
);
}
Counter.propTypes = {
score: React.PropTypes.number.isRequired,
onChange: React.PropTypes.func.isRequired,
}
function Player(props) {
return (
<div className="player">
<div className="player-name">
{props.name}
</div>
<div className="player-score">
<Counter score={props.score} onChange={props.onScoreChange} />
</div>
</div>
);
}
Player.propTypes = {
name: React.PropTypes.string.isRequired,
score: React.PropTypes.number.isRequired,
onScoreChange: React.PropTypes.func.isRequired,
};
/* Application holds state since players can change over time
can change state from application and cascade that state
down to Player and Counter
*/
var Application = React.createClass({
propTypes: {
title: React.PropTypes.string,
initialPlayers: React.PropTypes.arrayOf(React.PropTypes.shape({
name: React.PropTypes.string.isRequired,
score: React.PropTypes.number.isRequired,
id: React.PropTypes.number.isRequired,
})).isRequired,
},
//return object for default props
getDefaultProps: function() {
return {
title: "Scoreboard",
}
},
//return initial state for Players since can change # of players and number of players
getInitialState: function() {
return{
players: this.props.initialPlayers,
}
},
onScoreChange: function(index, delta) {
console.log("onScoreChange", index, delta);
this.state.players[index].score += delta;
this.setState(this.state);
},
onPlayerAdd: function(name) {
//console.log("player added", name);
//add player to state
this.state.players.push({
name: name,
score: 0,
id: nextId,
});
this.setState(this.state);
nextId += 1;
},
render: function() {
return (
<div className="scoreboard">
<Header title={this.props.title} players={this.state.players} />
<div className="players">
{this.state.players.map(function(player, index) {
return (
<Player
onScoreChange={
function(delta){this.onScoreChange(index, delta)}.bind(this)}
name={player.name}
score={player.score}
key={player.id} />
);
}.bind(this))}
</div>
<AddPlayerForm onAdd={this.onPlayerAdd} />
</div>
);
}
});
ReactDOM.render(<Application initialPlayers={PLAYERS}/>, document.getElementById('container'));
1 Answer
jobbol
Full Stack JavaScript Techdegree Student 17,885 PointsYour page refreshes because it's apart of the default feature when submitting a form.
Inside the onSubmit
your preventDefault
function is referenced instead of called. You have:
e.preventDefault;
You want
e.preventDefault();
Ashi A
2,531 Pointsthank Ashish and Josh.
Ashish Mehra
3,407 PointsAshish Mehra
3,407 Pointse.preventDefault should have parentheses