こんにちは、KOUKIです。Reactで画面開発を行なっています。
前回は、ユーザー一覧を実装をしました。今回は、Linkページの実装をします。
尚、「React, NextJS and Golang: A Rapid Guide – Advanced」コースを参考にしています。解釈は私が勝手に付けているので、本物をみたい場合は受講をお勧めします!
<目次>
前回
事前準備
フォルダ/ファイル
1 2 |
touch react-admin/src/models/link.ts touch react-admin/src/pages/Links.tsx |
Link画面
以前、Link APIを作成しました。
このAPIは、ユーザーとオーダーした商品をLinkさせるための APIです。
リクエスト時に、ユーザーのIDを紐付けて飛ばし、該当するLinkデータを取得します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// linkController.go func Link(ctx *fiber.Ctx) error { id, _ := strconv.Atoi(ctx.Params("id")) var links []models.Link database.DB.Where("user_id = ?", id).Find(&links) for i, link := range links { var orders []models.Order database.DB.Where("code = ? and complete = true", link.Code).Find(&orders) links[i].Orders = orders } return ctx.JSON(links) } |
今回は、ユーザーがオーダーした情報を確認できるLinkページを作成します。
LinkPropsの作成
Linkのモデルを作成しましょう。
1 2 3 4 5 6 |
// models/link.ts export interface Link { id: string code: string orders: any[] } |
Linkページの作成
続いて、Linkページを作成します。
なお、前回実装したUsersとほぼ同じであるため、説明は割愛します。
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 |
// pages/Links.tsx import { useEffect, useState } from 'react' import { Table, TableBody, TableRow, TableHead, TableCell, TableFooter, TablePagination } from '@material-ui/core' import { Link } from '../models/link' import Layout from '../components/Layout' import axios from 'axios' const Links = (props: any) => { const [links, setLinks] = useState<Link[]>([]) const [page, setPage] = useState(0) const perPage = 10 let linksUrl = `users/${props.match.params.id}/links` useEffect(() => { ( async () => { const { data } = await axios.get(linksUrl) setLinks(data) } )() }, []) return ( <Layout> <Table className="table table-striped table-sm"> <TableHead> <TableRow> <TableCell>#</TableCell> <TableCell>Code</TableCell> <TableCell>Count</TableCell> <TableCell>Revenue</TableCell> </TableRow> </TableHead> <TableBody> {/* perPageごとにユーザーをスライス */} {links.slice(page * perPage, (page + 1) * perPage).map(link => { return ( <TableRow key={link.id}> <TableCell>{link.id}</TableCell> <TableCell>{link.code}</TableCell> <TableCell>{link.orders.length}</TableCell> <TableCell>{link.orders.reduce((s, o) => s + o.total, 0)}</TableCell> </TableRow> ) })} </TableBody> <TableFooter> <TableRow> <TablePagination count={links.length} page={page} onChangePage={(e, newPage) => setPage(newPage)} rowsPerPageOptions={[]} rowsPerPage={perPage} ></TablePagination> </TableRow> </TableFooter> </Table> </Layout> ) } export default Links |
ルートの追加
「let linksUrl = users/${props.match.params.id}/links
」は、Link APIのエンドポイントであり、真ん中の「${props.match.params.id}」は、Reactのルートに指定したidを渡せます。
App.tsxにルートを追加しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// App.tsx .... import Links from './pages/Links' function App() { return ( <div className="App"> <BrowserRouter> ... <Route path={'/users/:id/links'} component={Links}></Route> </BrowserRouter> </div> ); } export default App; |
パスの中に「:id」を指定しており、これにより、先ほど示した「${props.match.params.id}」からIDとして取得できるようになります。
Linkページへのリンク
ユーザー情報の取得時に、IDも取得できるので、UserページからLinkページに遷移できるようにリンクを貼りましょう。
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 |
// pages/Users.tsx .... import { Button, Table, TableBody, TableRow, TableHead, TableCell, TableFooter, TablePagination } from '@material-ui/core ... const Users = () => { .... return ( <Layout> <Table className="table table-striped table-sm"> <TableHead>...</TableHead> <TableBody> {users.slice(page * perPage, (page + 1) * perPage).map(user => { return ( <TableRow key={user.id}> <TableCell>{user.id}</TableCell> <TableCell>{user.first_name} {user.last_name}</TableCell> <TableCell>{user.email}</TableCell> <TableCell> <Button variant="contained" color="primary" href={`users/${user.id}/links`} >View</Button> </TableCell> </TableRow> ) })} </TableBody> <TableFooter> <TableRow> <TablePagination...></TablePagination> </TableRow> </TableFooter> </Table> </Layout> ) } export default Users |
テーブルの最終列に「Button」を追加し、Linkページに飛べるようにしました。
検証
「http://localhost:3000/users」をブラウザから開き、VIEWボタンを押下すると、Linkページが表示されるようになります。
OKですね。
テーブルにデータが表示されない場合は、データが保存されていないのだと思います。
データを保存するページを作ると思うので、そこまでお待ちいただくか、APIへリクエストを送って、データを保存してから検証を行ってみてください。
登録するデータは結構あるので、大変かと思いますが…
次回
次回は、Productページを実装をしましょう。
Reactまとめ
参考書籍
ソースコード
ここまで実装したソースコードを下記に記載します。
Link.tsx
1 2 3 4 5 6 |
// models/link.ts export interface Link { id: string code: string orders: any[] } |
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 |
// App.tsx import './App.css'; import {BrowserRouter, Route} from 'react-router-dom' import {RedirectToUsers} from './components/RedirectToUsers' import Users from './pages/Users' import Login from './pages/Login' import Register from './pages/Register' import Links from './pages/Links' function App() { return ( <div className="App"> <BrowserRouter> <Route path={'/'} exact component={RedirectToUsers}></Route> <Route path={'/login'} component={Login}></Route> <Route path={'/register'} component={Register}></Route> <Route path={'/users'} exact component={Users}></Route> <Route path={'/users/:id/links'} component={Links}></Route> </BrowserRouter> </div> ); } export default App; |
Users.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 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 |
// pages/Users.tsx import { useEffect, useState } from 'react' import { UserProps } from '../models/user' import { Button, Table, TableBody, TableRow, TableHead, TableCell, TableFooter, TablePagination } from '@material-ui/core' import Layout from '../components/Layout' import axios from 'axios' const Users = () => { const [users, setUsers] = useState<UserProps[]>([]) // ページ情報のState const [page, setPage] = useState(0) const perPage = 10 let ambassadorsUrl = 'ambassadors' useEffect(() => { ( async () => { const { data } = await axios.get(ambassadorsUrl) setUsers(data) } )() }, []) return ( <Layout> <Table className="table table-striped table-sm"> <TableHead> <TableRow> <TableCell>#</TableCell> <TableCell>Name</TableCell> <TableCell>Name</TableCell> <TableCell>Actions</TableCell> </TableRow> </TableHead> <TableBody> {/* perPageごとにユーザーをスライス */} {users.slice(page * perPage, (page + 1) * perPage).map(user => { return ( <TableRow key={user.id}> <TableCell>{user.id}</TableCell> <TableCell>{user.first_name} {user.last_name}</TableCell> <TableCell>{user.email}</TableCell> <TableCell> <Button variant="contained" color="primary" href={`users/${user.id}/links`} >View</Button> </TableCell> </TableRow> ) })} </TableBody> <TableFooter> <TableRow> <TablePagination count={users.length} page={page} onChangePage={(e, newPage) => setPage(newPage)} rowsPerPageOptions={[]} rowsPerPage={perPage} ></TablePagination> </TableRow> </TableFooter> </Table> </Layout> ) } export default Users |
Links.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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
// pages/Links.tsx import { useEffect, useState } from 'react' import { Table, TableBody, TableRow, TableHead, TableCell, TableFooter, TablePagination } from '@material-ui/core' import { Link } from '../models/link' import Layout from '../components/Layout' import axios from 'axios' const Links = (props: any) => { const [links, setLinks] = useState<Link[]>([]) const [page, setPage] = useState(0) const perPage = 10 let linksUrl = `users/${props.match.params.id}/links` useEffect(() => { ( async () => { const { data } = await axios.get(linksUrl) setLinks(data) } )() }, []) return ( <Layout> <Table className="table table-striped table-sm"> <TableHead> <TableRow> <TableCell>#</TableCell> <TableCell>Code</TableCell> <TableCell>Count</TableCell> <TableCell>Revenue</TableCell> </TableRow> </TableHead> <TableBody> {/* perPageごとにユーザーをスライス */} {links.slice(page * perPage, (page + 1) * perPage).map(link => { return ( <TableRow key={link.id}> <TableCell>{link.id}</TableCell> <TableCell>{link.code}</TableCell> <TableCell>{link.orders.length}</TableCell> <TableCell>{link.orders.reduce((s, o) => s + o.total, 0)}</TableCell> </TableRow> ) })} </TableBody> <TableFooter> <TableRow> <TablePagination count={links.length} page={page} onChangePage={(e, newPage) => setPage(newPage)} rowsPerPageOptions={[]} rowsPerPage={perPage} ></TablePagination> </TableRow> </TableFooter> </Table> </Layout> ) } export default Links |
コメントを残す
コメントを投稿するにはログインしてください。