ReactでAPIを使って動的にページを表示する
Reactでアプリを作成する際、APIを利用してコンテンツを動的に表示させることが多いかと思います。
今回は簡単に、動的にデータの取得と表示する流れを確認します。ブログの雛形のような構成で作成していきます。
- パッケージ
"axios": "^1.1.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.4.2", "typescript": "^4.8.4",
ルーティングを設定するApp.tsxから順に確認します。
App.tsx
import React from 'react' import { BrowserRouter, Route, Routes } from 'react-router-dom' import Notes from './Notes' import Note from './Note' const App = () => ( <BrowserRouter> <h1>Notes</h1> <Routes> <Route path='/' element={<Notes />} /> <Route path=':slug' element={<Note />} /> </Routes> </BrowserRouter> ) export default App
ルーティングにはreact-router-dom
を利用します。基本的な使い方についてはこちらの記事を参照ください。
<Notes />
に記事一覧と、<Note />
に記事内容を表示するよう設定していきます。ファイルは全て同階層に設置しています。
. ├── App.tsx ├── Note.tsx ├── Notes.tsx ├── index.tsx └── types.ts
index.tsxはApp.tsxを表示しているだけです。
types.ts
export type NoteProps = { id?: string title?: string body?: string }
記事データ用に型ファイルを用意します。今回は確認のため最低限の設定です。
Notes.tsx
import React from 'react' import { useEffect, useState } from 'react' import { Link } from 'react-router-dom' import axios from 'axios' import { NoteProps } from './types' const Notes = () => { const [notes, setNotes] = useState([]) useEffect(() => { (async () => { const res = await axios.get('https://jsonplaceholder.typicode.com/posts') setNotes(res.data) })() }, []) return ( <ul> {notes.map((value: NoteProps) => ( <li key={value.id}> {value.id}: <Link to={`${value.id}`}> {value.title} </Link> </li> ))} </ul> ) } export default Notes
useState
はデータをnotesに格納するよう設定しています。
useEffect
でデータを取得し、setNotes
でnotesにデータを格納しています。また、非同期処理するため関数でラップします。useEffectについてはこちらの記事を参照ください。
データの取得はAPIの動作確認できるサービスJSONPlaceholder
を利用しています。フェッチは個人的によく利用するaxiosを使用しています。
notesで取得した記事データをreturn内のmapでLinkタグに設定しています。以上で、記事一覧のリンクが表示されます。
Note.tsx
import React from 'react' import { useEffect, useState } from 'react' import { Link, useParams } from 'react-router-dom' import axios from 'axios' import { NoteProps } from './types' const Note = () => { const slug = useParams().slug const [note, setNote] = useState<NoteProps>({}) useEffect(() => { (async () => { const res = await axios.get(`https://jsonplaceholder.typicode.com/posts/${slug}`) setNote(res.data) })() }, []) return ( <> <div>ID: {note.id}</div> <h2>{note.title}</h2> <div>{note.body}</div> <Link to='../'>記事一覧へ</Link> </> ) } export default Note
Notesの記事一覧からのリンクで記事IDを読み取り、IDに該当する記事データをAPIで取得します。
useParams
で:slug
を受け取ります。useEffect内でslugを使いAPIサーバーのURLを作成しています。作成したURLより記事のコンテンツをnoteに格納し、ページに表示しています。
以上で記事の表示が確認できます。indexページから各記事へ遷移し、それぞれ違ったコンテンツが表示できるのが確認できます。
PS
APIを利用して動的なページ表示ができました。
本来はaxiosのエラー対応が必要だったり、詳細な型定義を行ったり、ページ内でさらにデータフェッチしたりと、もっと複雑になると思いますが、ひとまず簡単にReactでのAPI利用の流れを確認しました。