React Forms Review
#
Set Up Inputs in a FormLet's add our inputs to state
this.state = { playlist: playlist, title: "", artist: "", time: "0:00",};
Let's add value to all three input fields
<form> <label htmlFor="song"> Song <input type="text" id="song" value={this.state.title} /> </label> <label htmlFor="artist"> Artist <input type="text" id="artist" value={this.state.artist} /> </label> <label htmlFor="time"> Time <input type="text" id="time" value={this.state.time} /> </label></form>
Now when we type in the input fields, they won't change.
Let's handle the input
handleChange(event) { this.setState({ [event.target.id]: event.target.value });}
Don't forget to bind it in the constructor
Add the event listener
<label htmlFor="song"> Song <input type="text" id="song" value={this.state.title} onChange={this.handleChange} /></label><label htmlFor="artist"> Artist <input type="text" id="artist" value={this.state.artist} onChange={this.handleChange} /></label><label htmlFor="time"> Time <input type="text" id="time" value={this.state.time} onChange={this.handleChange} /></label>
#
Get Submit functionality WorkingWrite our submit function (and don't forget to bind it in the constructor) (and don't forget to add onSubmit={this.handleSubmit} to your form tag)
Remember, submit's default behavior is to refresh the page. Let's be sure to prevent that default.
We should not ever mutate state directly. We must update state with this.setState()
First, we're going to create a new object with our state we collected from our inputs.
Then we are going to make a new array, using the destructuring spread operator so that we don't alter state outside of setState
.
Finally, inside of setState, we'll update our songs array to our new array
handleSubmit(event) { event.preventDefault(); const newSong = { title: this.state.title, artist: this.state.artist, time: this.state.time, };
const updatedSongs = [...this.state.playlists.songs, newSong];
this.setState({ playlists: updatedSongs, name: "", artist: "", time: "0:00", });}
It would be nice to clear the fields. We can do this by updating state a bit more
this.setState({ playlist: updatedPlaylist, title: "", artist: "", time: "0:00",});
Bonus: Can you figure out how you would delete a song?
Your final App.js
should look something like this:
import React, { Component } from "react";import Footer from "./components/Footer";import Header from "./components/Header";import playlist from "./data.js";
class App extends Component { constructor(props) { super(props); this.state = { playlist: playlist, title: "", artist: "", time: "0:00", }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({ [event.target.id]: event.target.value }); } handleSubmit(event) { event.preventDefault();
const newSong = { title: this.state.title, artist: this.state.artist, time: this.state.time, }; console.log(newSong); const updatedPlaylist = [newSong, ...this.state.playlist];
this.setState({ playlist: updatedPlaylist, title: "", artist: "", time: "0:00", }); } render() { return ( <div> <Header /> <form onSubmit={this.handleSubmit}> <label htmlFor="title"> Song <input type="text" id="title" value={this.state.title} onChange={this.handleChange} /> </label> <label htmlFor="artist"> Artist <input type="text" id="artist" value={this.state.artist} onChange={this.handleChange} /> </label> <label htmlFor="time"> Time <input type="text" id="time" value={this.state.time} onChange={this.handleChange} /> </label> <label> <input type="submit" /> </label> </form> <main> <div> <h3>Playlist 1</h3> <table> <thead> <tr> <th>Song</th> <th>Arist</th> <th>Time</th> </tr> </thead> <tbody> {this.state.playlist.map((song, index) => { return ( <tr key={index}> <td>{song.title}</td> <td>{song.artist}</td> <td>{song.time}</td> </tr> ); })} </tbody> </table> </div> </main> <Footer /> </div> ); }}
export default App;