React学習2(外部データの読み込みと表示)
React復習がてら要点をまとめていく。
外部ファイルの配列形式のデータを読み込んできて、画面に表示する例。
要点整理
- Conditional renderingをするときは、returnするブロックを別メソッドで分けておくとやりやすい。
- 読み込むデータに対してgetter, setter的なファンクションを用意しておくとデータ操作しやすくて便利。
ファイル構成
Vidly.jsx
import React, { Component } from 'react' import { getMovies } from './data/services/fakeMovieService' class Vidly extends Component { state = { movies: getMovies(), } render() { return ( <div className="container"> <main className="container" role="main"> <h1>Vidly</h1> {this.renderMovies()} </main> </div> ) } renderMovies = () => { const { movies } = this.state if (movies.length === 0) return <p>There are no movies!</p> return ( <> <p>There are {movies.length} movies!</p> <table className="table"> <thead> <tr> <th scope="col">id</th> <th scope="col">Title</th> <th scope="col">Genre</th> <th></th> </tr> </thead> <tbody> {movies.map((movie, index) => ( <tr key={index}> <th scope="row">{movie._id}</th> <td>{movie.title}</td> <td>{movie.genre.name}</td> <td> <button onClick={() => this.handleDelete(movie)} type="button" className="btn btn-danger" > Delete </button> </td> </tr> ))} </tbody> </table> </> ) } handleDelete = movie => { const filteredMovies = this.state.movies.filter(m => { return m !== movie }) this.setState({ movies: filteredMovies, }) } } export default Vidly
fakeMovieService.js
import * as genresAPI from './fakeGenreService' const movies = [ { _id: '5b21ca3eeb7f6fbccd471815', title: 'Terminator', genre: { _id: '5b21ca3eeb7f6fbccd471818', name: 'Action' }, numberInStock: 6, dailyRentalRate: 2.5, publishDate: '2018-01-03T19:04:28.809Z', }, { _id: '5b21ca3eeb7f6fbccd471816', title: 'Die Hard', genre: { _id: '5b21ca3eeb7f6fbccd471818', name: 'Action' }, numberInStock: 5, dailyRentalRate: 2.5, }, { _id: '5b21ca3eeb7f6fbccd471817', title: 'Get Out', genre: { _id: '5b21ca3eeb7f6fbccd471820', name: 'Thriller' }, numberInStock: 8, dailyRentalRate: 3.5, }, { _id: '5b21ca3eeb7f6fbccd471819', title: 'Trip to Italy', genre: { _id: '5b21ca3eeb7f6fbccd471814', name: 'Comedy' }, numberInStock: 7, dailyRentalRate: 3.5, }, { _id: '5b21ca3eeb7f6fbccd47181a', title: 'Airplane', genre: { _id: '5b21ca3eeb7f6fbccd471814', name: 'Comedy' }, numberInStock: 7, dailyRentalRate: 3.5, }, { _id: '5b21ca3eeb7f6fbccd47181b', title: 'Wedding Crashers', genre: { _id: '5b21ca3eeb7f6fbccd471814', name: 'Comedy' }, numberInStock: 7, dailyRentalRate: 3.5, }, { _id: '5b21ca3eeb7f6fbccd47181e', title: 'Gone Girl', genre: { _id: '5b21ca3eeb7f6fbccd471820', name: 'Thriller' }, numberInStock: 7, dailyRentalRate: 4.5, }, { _id: '5b21ca3eeb7f6fbccd47181f', title: 'The Sixth Sense', genre: { _id: '5b21ca3eeb7f6fbccd471820', name: 'Thriller' }, numberInStock: 4, dailyRentalRate: 3.5, }, { _id: '5b21ca3eeb7f6fbccd471821', title: 'The Avengers', genre: { _id: '5b21ca3eeb7f6fbccd471818', name: 'Action' }, numberInStock: 7, dailyRentalRate: 3.5, }, ] export function getMovies() { return movies } export function getMovie(id) { return movies.find(m => m._id === id) } export function saveMovie(movie) { let movieInDb = movies.find(m => m._id === movie._id) || {} movieInDb.name = movie.name movieInDb.genre = genresAPI.genres.find(g => g._id === movie.genreId) movieInDb.numberInStock = movie.numberInStock movieInDb.dailyRentalRate = movie.dailyRentalRate if (!movieInDb._id) { movieInDb._id = Date.now() movies.push(movieInDb) } return movieInDb } export function deleteMovie(id) { let movieInDb = movies.find(m => m._id === id) movies.splice(movies.indexOf(movieInDb), 1) return movieInDb }
fakeGenreService.js
export const genres = [ { _id: '5b21ca3eeb7f6fbccd471818', name: 'Action' }, { _id: '5b21ca3eeb7f6fbccd471814', name: 'Comedy' }, { _id: '5b21ca3eeb7f6fbccd471820', name: 'Thriller' }, ] export function getGenres() { return genres.filter(g => g) }