こんにちは、KOUKIです。
Reactで、Top画面を実装します。
尚、「React, NextJS and Golang: A Rapid Guide – Advanced」コースを参考にしています。解釈は私が勝手に付けているので、本物をみたい場合は受講をお勧めします!
<目次>
前回
事前準備
ファイル
1 2 3 4 5 6 |
mkdir react-ambassador/src/components touch react-ambassador/src/components/Nav.tsx touch react-ambassador/src/components/Header.tsx touch react-ambassador/src/components/Layout.tsx mkdir react-ambassador/src/pages touch react-ambassador/src/pages/ProductsFrontend.tsx |
モジュール
1 2 3 |
cd react-ambassador/ npm i react-router-dom axios npm i -D @types/react-router-dom |
package.json
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 |
{ "name": "react-ambassador", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", "@types/jest": "^26.0.15", "@types/node": "^12.0.0", "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", "axios": "^0.21.1", "react": "^17.0.2", "react-dom": "^17.0.2", "react-router-dom": "^5.2.0", "react-scripts": "4.0.3", "typescript": "^4.1.2", "web-vitals": "^1.0.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "devDependencies": { "@types/react-router-dom": "^5.1.8" } } |
画面開発
Bootstrapのテンプレートを参考に、「Bootstrapを導入->コンポーネントの作成->Topページの作成->ルーティング設定」の順に実装します。
Bootstrapの導入
CSSのWebフレームワークであるBootstrapを使ってみましょう。
まず、react-ambassadorのpublicフォルダ配下にあるindex.htmlにBootstrapのCDNを書きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!-- public/index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <!-- BootStrap --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <title>React App</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html> |
Navコンポーネントの作成
ナビゲーションになるコンポーネントを実装します。
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 |
// components/Nav.tsx const Nav = () => { return ( <header> <div className="collapse bg-dark" id="navbarHeader"> <div className="container"> <div className="row"> <div className="col-sm-8 col-md-7 py-4"> <h4 className="text-white">About</h4> <p className="text-muted">Add some information about the album below, the author, or any other background context. Make it a few sentences long so folks can pick up some informative tidbits. Then, link them off to some social networking sites or contact information.</p> </div> <div className="col-sm-4 offset-md-1 py-4"> <h4 className="text-white">Contact</h4> <ul className="list-unstyled"> <li><a href="#" className="text-white">Follow on Twitter</a></li> <li><a href="#" className="text-white">Like on Facebook</a></li> <li><a href="#" className="text-white">Email me</a></li> </ul> </div> </div> </div> </div> <div className="navbar navbar-dark bg-dark shadow-sm"> <div className="container"> <a href="#" className="navbar-brand d-flex align-items-center"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true" className="me-2" viewBox="0 0 24 24"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg> <strong>Album</strong> </a> <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarHeader" aria-controls="navbarHeader" aria-expanded="false" aria-label="Toggle navigation"> <span className="navbar-toggler-icon"></span> </button> </div> </div> </header> ) } export default Nav |
Headerコンポーネントの作成
ヘッダーのコンポーネントを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// components/Header.tsx const Header = () => { return ( <section className="py-5 text-center container"> <div className="row py-lg-5"> <div className="col-lg-6 col-md-8 mx-auto"> <h1 className="fw-light">Album example</h1> <p className="lead text-muted">Something short and leading about the collection below—its contents, the creator, etc. Make it short and sweet, but not too short so folks don’t simply skip over it entirely.</p> <p> <a href="#" className="btn btn-primary my-2">Main call to action</a> <a href="#" className="btn btn-secondary my-2">Secondary action</a> </p> </div> </div> </section> ) } export default Header |
Layoutコンポーネントの作成
レイアウトのコンポーネントを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// components/Layout.tsx import Nav from './Nav' import Header from './Header' const Layout = (props: any) => { return ( <div> <Nav /> <main> <Header /> <div className="album py-5 bg-light"> <div className="container"> {props.children} </div> </div> </main> </div> ) } export default Layout |
Top画面の作成
Top画面を作成します。
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 |
// pages/ProductsFrontend.tsx import Layout from '../components/Layout' const ProductsFrontend = () => { return ( <Layout> <div className="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3"> <div className="col"> <div className="card shadow-sm"> <svg className="bd-placeholder-img card-img-top" width="100%" height="225" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Placeholder: Thumbnail" preserveAspectRatio="xMidYMid slice" focusable="false"><title>Placeholder</title><rect width="100%" height="100%" fill="#55595c"/><text x="50%" y="50%" fill="#eceeef" dy=".3em">Thumbnail</text></svg> <div className="card-body"> <p className="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p> <div className="d-flex justify-content-between align-items-center"> <div className="btn-group"> <button type="button" className="btn btn-sm btn-outline-secondary">View</button> <button type="button" className="btn btn-sm btn-outline-secondary">Edit</button> </div> <small className="text-muted">9 mins</small> </div> </div> </div> </div> </div> </Layout> ) } export default ProductsFrontend |
ルーティングの設定
ルーティングの設定を行いましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// App.tsx import { BrowserRouter, Route } from 'react-router-dom' import ProductsFrontend from './pages/ProductsFrontend' import './App.css'; function App() { return ( <BrowserRouter> <Route path={'/'} component={ProductsFrontend} /> </BrowserRouter> ); } export default App; |
ページ検証
以下のコマンドで、Dockerを立ち上げてください。
1 |
docker-compose up ambassador |
Dockerが立ち上がったら、ブラウザから「http://localhost:4000/」へアクセスします。

OKですね。
次回
次回は、Admin画面にも実装した共通処理を作成しましょう。
コメントを残す
コメントを投稿するにはログインしてください。