こんにちは、KOUKIです。
ReactでMovie Appの開発を行なっています。
今回は、ページのコンポーネント化とReactのStateを実装しましょう。
尚、Udemyの「Working with React and Go (Golang)」を参考にしているので、よかったら受講してみてください。
前回
事前準備
フォルダ/ファイル
1 2 3 4 5 6 |
mkdir go-movies/src/components touch go-movies/src/components/Home.tsx touch go-movies/src/components/Admin.tsx touch go-movies/src/components/Movies.tsx mkdir go-movies/src/models touch go-movies/src/models/movie.ts |
ページのコンポーネント化
Reactでは、ページをコンポーネント単位で作成すると再利用性の高いコードを実装することができます。
Homeページ
前回作成したHomeをコンポーネント化しましょう。
1 2 3 4 5 6 7 8 9 |
// components/Home.tsx const Home = () => { return ( <h2>Home</h2> ) } export default Home |
Movieページ
前回作成したMovieをコンポーネント化しましょう。
1 2 3 4 5 6 7 8 9 |
// components/Movies.tsx const Movies = () => { return ( <h2>Choose a movie</h2> ) } export default Movies |
Adminページ
前回作成したAdminをコンポーネント化しましょう。
1 2 3 4 5 6 7 8 9 10 |
// components/Admin.tsx const Admin = () => { return ( <h2>Manage Catalog</h2> ) } export default Admin |
App.tsxから読み込む
作成したコンポーネントをApp.tsxから読み込みましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// src/App.tsx import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom' // 読み込み import Home from './components/Home' import Movies from './components/Movies' import Admin from './components/Admin' export default function App() { ... } // const Home = () => { // return <h2>Home</h2> // } // const Movies = () => { // return <h2>Movies</h2> // } // const Admin = () => { // return <h2>Manage Catalog</h2> // } |
確認
画面遷移ができていれば、成功です。
Movie情報を表示する
Reactには、State(状態)を管理する機能として「useState」提供されています。
例えば、Movie情報をこのuseStateに渡すとReactアプリ内で管理することができるようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// components/Movies.tsx import { useEffect, useState, Fragment } from 'react' import { Movie } from '../models/movie' const Movies = () => { // 仮のデータ const tmpData = [ {id: 1, title: "The Shawshank Redemption", runtime: 142}, {id: 2, title: "Harry Potter", runtime: 175}, {id: 3, title: "The Dark Kngiht", runtime: 142}, ] const [movies, setMovies] = useState<Movie[]>([]) useEffect(() => { ( () => { setMovies(tmpData) } )() }, []) // 空配列を第二引数に渡すとマウント・アンマウント時のみ第1引数の関数を実行 ... } |
「const [movies, setMovies] = useState<Movie[]>([])」の行で、Stateを設定しています。
型には、新しく実装したMovieを指定しました。
1 2 3 4 5 6 |
// models/movie.ts export interface Movie { id: number title: string runtime: number } |
また、useEffectを利用してページが読み込まれたタイミングで、Movie情報をStateに格納しています。
Movie情報は、以下の処理で画面に表示することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// components/Movies.tsx ... const Movies = () => { ... return ( <Fragment> <h2>Choose a movie</h2> <ul> {movies.map((m) => { return ( <li key={m.id}> {m.title} </li> ) })} </ul> </Fragment> ) } export default Movies |

補足:Reactのライフサイクル
Reactのライフサイクルは結構複雑なのですが、このDocumentは結構参考になります。
※クラスコンポーネントで実装した時の用語で説明されています

次回
次回は、ルーティング処理の実装をしましょう。
記事まとめ
参考書籍
ソースコード
ここまで実装したソースコードを下記に記載します。
App.tsx
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 |
// src/App.tsx import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom' import Home from './components/Home' import Movies from './components/Movies' import Admin from './components/Admin' export default function App() { return ( <Router> <div className="container"> <div className="row"> <h1 className="mt-3"> Go Watch a Movie! </h1> <hr className="mb-3" /> </div> <div className="row"> <div className="col-md-2"> <nav> <ul className="list-group"> <li className="list-group-item"> <Link to="/">Home</Link> </li> <li className="list-group-item"> <Link to="/movies">Movies</Link> </li> <li className="list-group-item"> <Link to="/admin">Manage Catalog</Link> </li> </ul> </nav> </div> <div className="col-md-10"> <Switch> <Route path="/movies"> <Movies /> </Route> <Route path="/admin"> <Admin /> </Route> <Route path="/"> <Home /> </Route> </Switch> </div> </div> </div> </Router> ) } |
Home.tsx
1 2 3 4 5 6 7 8 9 10 |
// components/Home.tsx const Home = () => { return ( <h2>Home</h2> ) } export default Home |
Movie.tsx
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 |
// components/Movies.tsx import { useEffect, useState, Fragment } from 'react' import { Movie } from '../models/movie' const Movies = () => { // 仮のデータ const tmpData = [ {id: 1, title: "The Shawshank Redemption", runtime: 142}, {id: 2, title: "Harry Potter", runtime: 175}, {id: 3, title: "The Dark Kngiht", runtime: 142}, ] const [movies, setMovies] = useState<Movie[]>([]) useEffect(() => { ( () => { setMovies(tmpData) } )() }, []) // 空配列を第二引数に渡すとマウント・アンマウント時のみ第1引数の関数を実行 return ( <Fragment> <h2>Choose a movie</h2> <ul> {movies.map((m) => { return ( <li key={m.id}> {m.title} </li> ) })} </ul> </Fragment> ) } export default Movies |
Admin.tsx
1 2 3 4 5 6 7 8 9 10 |
// components/Admin.tsx const Admin = () => { return ( <h2>Manage Catalog</h2> ) } export default Admin |
Movie.ts
1 2 3 4 5 6 |
// models/movie.ts export interface Movie { id: number title: string runtime: number } |
コメントを残す
コメントを投稿するにはログインしてください。