ReactでDjango REST frameworkのバックエンドAPIと連携してタスク一覧を表示させる
はじめに
【フロントエンドとの連携】CORS設定でフロントエンドからAPIを呼び出せるようにするでフロントエンドとの連携に必要なCORS設定を行った。
今回はReactを使用して、DRFとの連携を行い、最終的にはタスク一覧をReactの開発環境で表示させる。
viteを使ってReactプロジェクトを作成
vite(ヴィート)は、ReactやVueのフロントエンド開発で使われる高速なビルドツール。
ビルドツールとは、プログラムの開発において、ソースコードを変換・最適化して実行可能な形式にするためのツール。
新規Reactプロジェクトを使用するので、gitでリポジトリを作成した。

ローカルにもフォルダを作成する。

リポジトリの初期化を行なった。
Mac:react_todo shibatahiroshitaka$ git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
Initialized empty Git repository in /Users/shibatahiroshitaka/Downloads/react/react_todo/.git/
Mac:react_todo shibatahiroshitaka$ git remote add origin https://github.com/ki-hi-ro/react_todo.git
Mac:react_todo shibatahiroshitaka$
現状、react_todoにいるので、以下のコマンドを使用すると、react_todoの中にreact_todoが作成されてしまう。
npm create vite@latest react_todo --template react
カレントディレクトリにインストールするには、フォルダ名の代わりに「.」を使用する。
npm create vite@latest . --template react
フレームワークとバリアント(フレームワークの設定)を選択したらreactのプロジェクトフォルダの中身がインストールされた。
Mac:react_todo shibatahiroshitaka$ npm create vite@latest . --template react
│
◇ Select a framework:
│ React
│
◇ Select a variant:
│ TypeScript + SWC
│
◇ Scaffolding project in /Users/shibatahiroshitaka/Downloads/react/react_todo...
│
└ Done. Now run:
npm install
npm run dev

SWC(Speedy Web Compiler)は、Rustで書かれた超高速なJS/TSのコンパイラのこと。
Rustは、C++の代替として開発され、メモリ安全性を保証しつつ、高パフォーマンスを実現できるのが特徴。
必要なパッケージをインストール
npm installで140個のパッケージをインストールした。WARNという警告が出ていたが、以下では省略した。
Mac:react_todo shibatahiroshitaka$ npm install
added 140 packages, and audited 141 packages in 11s
40 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
node_modulesはgitignoreに入っていた。量が多いためと考えられる。

Django REST frameworkとの通信には、axiosを使用するので、追加でインストールする。
Mac:react_todo shibatahiroshitaka$ npm install axios
added 23 packages, and audited 164 packages in 2s
46 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
ReactからDjango APIにアクセス
Django側のAPI(http://127.0.0.1:8000/api/tasks/)からデータを取得し、ReactのuseEffectを使って一覧を表示するコンポーネントを作成する。
useEffectとは、Reactのフック(Hook)の一つで副作用(Side Effects)を処理するための関数。
フックとは、Reactの関数コンポーネントに「状態管理」や「ライフサイクル処理」を追加するための関数。
関数コンポーネント(Functional Component)とは、ReactでUIを定義するための関数ベースのコンポーネント。
副作用とは、関数の外部に影響を与える処理のこと。関数は通常、入力(引数)に対して出力(返り値)を返すだけ。以下のようなコンソールログは、関数の外(コンソール)に影響を与えるため、副作用の一つ。
console.log('AAA');
APIからデータを取得するのは副作用なので、useEffectによって適切に制御する必要がある。
TaskList.jsを作成
src/components/TaskList.jsを作成して、APIからデータを取得して表示する。
import { useState, useEffect } from "react";
import axios from "axios";
const API_URL = "http://127.0.0.1:8000/api/tasks/";
const TaskList = () => {
const [tasks, setTasks] = useState([]);
useEffect(() => {
axios.get(API_URL)
.then(response => setTasks(response.data))
.catch(error => console.error("Error fetching tasks:", error));
}, []);
return (
<div>
<h2>タスク一覧</h2>
<ul>
{tasks.map(task => (
<li key={task.id}>{task.title}</li>
))}
</ul>
</div>
);
};
export default TaskList;
useStateとは、Reactのフックの一つで、関数コンポーネント内で状態を管理するための関数。
以下の部分では、useStateフックで「tasks」という状態を定義している。setTasksはそれを更新するもの。useState([])では、初期値として空の配列([])を設定している。
const [tasks, setTasks] = useState([]);
この辺の解説記事は別途書いていく。
TypeScriptを選択していたので、TaskList.jsをTaskList.tsxに変更する。
拡張子と以下の太字部分を修正した。
import { useState, useEffect } from "react";
import axios from "axios";
const API_URL = "http://127.0.0.1:8000/api/tasks/";
interface Task {
id: number;
title: string;
}
const TaskList: React.FC = () => {
const [tasks, setTasks] = useState<Task[]>([]);
useEffect(() => {
axios.get<Task[]>(API_URL)
.then(response => setTasks(response.data))
.catch(error => console.error("Error fetching tasks:", error));
}, []);
return (
<div>
<h2>タスク一覧</h2>
<ul>
{tasks.map(task => (
<li key={task.id}>{task.title}</li>
))}
</ul>
</div>
);
};
export default TaskList;
TaskList.jsをTaskList.tsxに変更 · ki-hi-ro/react_todo@46c1b47
App.tsxに組み込む
src/App.tsxを修正し、TaskListコンポーネントを表示する。
デフォルトのApp.tsxはこちら。
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
function App() {
const [count, setCount] = useState(0)
return (
<>
<div>
<a href="https://vite.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
}
export default App
既存の記述はほとんど削除して以下に書き換えた。
import TaskList from "./components/TaskList";
function App() {
return (
<div>
<h1>タスク管理アプリ</h1>
<TaskList/>
</div>
);
}
export default App
importのところでtsのエラーが出ている。

モジュール './components/TaskList' の宣言ファイルが見つかりませんでした。'/Users/hiroki/Downloads/react_todo/src/components/TaskList.js' は暗黙的に 'any' 型になります。ts(7016)
このエラーの原因は、TypeScriptがTaskList.tsxを正しく認識できていないということ。
VSCodeを開き直したら、TaskList.tsxを正しく認識してくれたのかエラーが解消されていた。

App.tsxを修正 · ki-hi-ro/react_todo@094f5a2
Reactの開発サーバーを起動

TaskList.jsが残っていたことによるエラーを解決して、npm run devで開発サーバーを起動すると上記の画面になった。
当初の想定としては、DjangoのバックエンドAPIで構築したタスクデータをReactのフロントエンドに表示させることだったので、それを目指していこう。
データを表示させる
CORS設定を見直すことで、発生していた3つのエラーが芋づる式に解決したで奮闘した結果、以下のようにDjangoのバックエンドで作成したデータをAPIで取得して、フロントエンドのReactで表示させることができた。

コメントを残す