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 trialCarey Cade
5,283 PointsWhy not use array push() method?
Why don't we just use an array push() method to add the new guest object into the state.guests array?
Thanks:)
5 Answers
Seth Kroger
56,413 PointsThou Shalt Not Alter State Directly.
That's pretty much a commandment-level dictum in React. Every time you want to change it you should use setState() handing it the new info to put there. Since push() adds to the existing array instead of returning a new one it goes against that principle.
https://facebook.github.io/react/docs/state-and-lifecycle.html#using-state-correctly
Abraham Juliot
47,353 PointsUseful note on this topic at https://stackoverflow.com/questions/26253351/correct-modification-of-state-arrays-in-reactjs
Anthony Albertorio
22,624 PointsMontalvo Miguelo You are still modifying state directly, via modifying the pervious state. From what I understand, modifying any sort of state directly is not recommended in React.
See the React docs for more information: https://reactjs.org/docs/state-and-lifecycle.html
Also, see this great post: https://medium.com/@shopsifter/using-a-function-in-setstate-instead-of-an-object-1f5cfd6e55d1
A better way could be by just updating the new state like this:
class App extends Component {
//...
newGuestSubmitHandler = e => {
e.preventDefault();
if (this.state.pendingGuest !== "") {
const newPerson = {
name: this.state.pendingGuest,
isConfirmed: false,
isEditing: false
};
this.setState(prevState => ({
guests: [newPerson, ...prevState.guests],
pendingGuest: ""
}));
}
}
//...
}
Montalvo Miguelo
24,789 PointsYou can pass a function to setState
method, that function receives the prevState
and props
as arguments so you could use push as follows:
class App extends Component {
//...
newsGuestSubmitHandler(event) {
event.preventDefault();
this.setState((prevState, props) => {
prevState.guests.push({
name: this.state.pendingGuest,
isEditing: false,
isConfirmed: false
});
return {
guests: prevState.guests,
pendingGuest: ''
}
});
}
}
Charles Wanjohi
9,235 PointsArray push method would add the new guest object at the end of the array while the intention here is to add it as the first object (index 0) in the array.Otherwise its still possible but the new object would be added at the end i.e it wont be rendered as the first guest component.The implementation would be a little different though
Carey Cade
5,283 PointsThanks Charles!
Aaron Smith
19,091 PointsI initially wrote my new guest handler like Carey was thinking, using unshift
instead of push
so that the new guest object gets added to the first position in the array:
addNewGuest = e => {
e.preventDefault();
this.state.guests.unshift({
name: this.state.pendingGuest,
isConfirmed: false,
isEditing: false
});
this.setState({
pendingGuest: ''
});
}
I tested it and got the same functionality Guil got in the video using the spread operator inside of the setState() function. I can accept that this is not best practice, but I'm wondering if there is any actual disadvantage to coding it this way.
Carey Cade
5,283 PointsCarey Cade
5,283 PointsHey Seth! I know that of the importance of using setState(). In theory, couldn't one add to the existing array, and then setState() to be that new array? Is that incorrect... or just not best practice? Thanks so much!
Seth Kroger
56,413 PointsSeth Kroger
56,413 Pointspush() will modify the current array in state. There won't be a "new" array, just a changed old one and that would be incorrect with the way React wants to do things.