Summary
Read (Single)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | class MovieList extends React.Component { state = { movie: { title: 'Terminator', id: 1 } }; render () { return ( <ul> <Movie title={this.state.movie.title} id={this.state.movie.id} /> </ul> ); } } class Movie extends React.Component { render () { return ( <li>{this.props.title}</li> ); } } ReactDOM.render(<MovieList />, document.getElementById('content')); |
Read (Multiple)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | class MovieList extends React.Component { state = { movies: [ { title: 'Terminator', id: 1 }, { title: 'Waterboy', id: 2 } ] }; render () { const movieComponents = this.state.movies.map((movie) => ( <Movie key={movie.id} title={movie.title} id={movie.id} /> )); return ( <ul> {movieComponents} </ul> ); } } class Movie extends React.Component { render () { return ( <li>{this.props.title}</li> ); } } ReactDOM.render(<MovieList />, document.getElementById('content')); |
- Note the difference between Read (Single) vs. Read (Multiple)
- We declared a variable to store the list of movie components above the return statement.
- We use the array.map function to loop through the list of movies. array.map will create a "copy" of the array so we don't mutate it by accident.
- Each movie component must have a unique key value, so we used movie.id
- The return statement uses the {movieComponents} variable in the JSX
Create
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | class MovieList extends React.Component { state = { movies: [ { title: 'Terminator', id: 1 }, { title: 'Waterboy', id: 2 } ] }; handleFormSubmit = (movie) => { this.createMovie(movie); }; createMovie = (movie) => { const newMovie = { title: movie.title, id: uuid.v4() }; this.setState({ movies: this.state.movies.concat(newMovie), }); }; render () { const movieComponents = this.state.movies.map((movie) => ( <Movie key={movie.id} title={movie.title} id={movie.id} /> )); return ( <div> <ul> {movieComponents} </ul> <AddMovieForm onFormSubmit={this.handleFormSubmit} /> </div> ); } } class Movie extends React.Component { render () { return ( <li>{this.props.title}</li> ); } } class AddMovieForm extends React.Component { state = { title: this.props.title || '' }; handleTitleChange = (e) => { this.setState({ title: e.target.value }); }; handleSubmit = () => { this.props.onFormSubmit({ title: this.state.title }); this.setState({ title: '' }); }; render () { return ( <div> <input type='text' value={this.state.title} onChange={this.handleTitleChange} /> <button onClick={this.handleSubmit}>Submit</button> </div> ); } } ReactDOM.render(<MovieList />, document.getElementById('content')); |
Update
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | class MovieList extends React.Component { state = { movies: [ { title: 'Terminator', id: 1 }, { title: 'Waterboy', id: 2 } ] }; handleFormSubmit = (movie) => { this.updateMovie(movie); }; updateMovie = (attrs) => { this.setState({ movies: this.state.movies.map((movie) => { if (movie.id === attrs.id) { return Object.assign({}, movie, { title: attrs.title }); } else { return movie; } }), }); }; render () { const movieComponents = this.state.movies.map((movie) => ( <EditableMovie key={movie.id} title={movie.title} id={movie.id} onFormSubmit={this.handleFormSubmit} /> )); return ( <div> <ul> {movieComponents} </ul> </div> ); } } class EditableMovie extends React.Component { state = { isEditing: false }; handleEditClick = () => { this.setState({ isEditing: true }); }; handleFormSubmit = (movie) => { this.props.onFormSubmit(movie); this.setState({ isEditing: false }); } render () { if (this.state.isEditing) { return ( <MovieForm title={this.props.title} id={this.props.id} onFormSubmit={this.handleFormSubmit} /> ); } else { return ( <Movie title={this.props.title} id={this.props.id} onEditClick={this.handleEditClick} /> ); } } } class Movie extends React.Component { render () { return ( <li> {this.props.title} <button onClick={this.props.onEditClick}>Edit</button> </li> ); } } class MovieForm extends React.Component { state = { title: this.props.title || '' }; handleTitleChange = (e) => { this.setState({ title: e.target.value }); }; handleFormSubmit = () => { this.props.onFormSubmit({ id: this.props.id, title: this.state.title }); }; render () { return ( <div> <input type="text" value={this.state.title} onChange={this.handleTitleChange} /> <button onClick={this.handleFormSubmit}>Save</button> </div> ); } } ReactDOM.render(<MovieList />, document.getElementById('content')); |
Delete
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | class MovieList extends React.Component { state = { movies: [ { title: 'Terminator', id: 1 }, { title: 'Waterboy', id: 2 } ] }; // Delete is handled here handleMovieDelete = (movieId) => { this.deleteMovie(movieId); }; deleteMovie = (movieId) => { this.setState({ movies: this.state.movies.filter(m => m.id !== movieId) }); }; render () { const movieComponents = this.state.movies.map((movie) => ( <Movie key={movie.id} title={movie.title} id={movie.id} onDeleteClick={this.handleMovieDelete} // Delete handler is passed down here /> )); return ( <ul> {movieComponents} </ul> ); } } class Movie extends React.Component { onDeleteClick = () => { this.props.onDeleteClick(this.props.id); // Parent Delete handler is invoked here }; render () { return ( <li>{this.props.title} <button onClick={this.onDeleteClick}>Delete</button> </li> ); } } ReactDOM.render(<MovieList />, document.getElementById('content')); |
- The filter function is used to remove an item from state because it will create a "copy" of the array to and return that, which guarantees we don't violate our rule about immutable items within state.
- I created a separate function for performing the delete, as opposed to putting it in handleMoveDelete so we call deleteMovie from another place if we need to.
No comments:
Post a Comment