はじめに
こんにちは、エンジニアのkeitaMaxです。
Laravel10とInertia.jsでReactを使用して画像アップロードをし、保存する処理を作成したいと思います。
Laravel側
保存する処理を作成します。
まず、web.phpでAPIの作成と、アップロード画面を表示するためのRouteを作ります。
web.php
Route::post('/image_upload', [ImageController::class, 'index']);
Route::post('/api/upload', [ImageController::class, 'upload'])->withoutMiddleware(VerifyCsrfToken::class)->name('upload');
次にImageController
を作成していきます。
ImageController
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Image;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class ImageController extends Controller
{
public function index(Request $request)
{
return Inertia::render('Image');
}
public function upload(Request $request)
{
$path = $request->file('image')->store('images', 'public');
$url = config('app.image_url') . Storage::url($path);
return response()->json(['url' => $url], 201);
}
}
indexでReactの画面を表示していて、uploadで実際にアップロードした画像を保存してURLを作成して返しています。
React側
以下のように作成しました。
Image.tsx
import React, { useState } from 'react';
export const Image = React.memo(function Image() {
const [image, setImage] = useState(null);
const handleImageChange = (e: any) => {
setImage(e.target.files[0]);
};
const handleSubmit = async (e: any) => {
e.preventDefault();
if (!image) return
const formData = new FormData();
formData.append('image', image);
try {
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest',
},
});
if (!response.ok) {
throw new Error('ネットワークエラーが発生しました。');
}
const result = await response.json();
console.log(result); // サーバーからのレスポンスを処理
alert("画像がアップロードされました。");
} catch (error) {
console.error('エラー:', error);
alert("画像のアップロードに失敗しました。");
}
};
return (
<div>
<h1>画像アップロード</h1>
<form onSubmit={handleSubmit}>
<input type="file" onChange={handleImageChange} />
<button type="submit">アップロード</button>
</form>
</div>
);
})
export default Image
npm run dev
をすると以下のような画面がでてくるので、画像をアップロードすると、URLが返ってきます。
画像を見る
返ってきたURLにアクセスしただけだと画像をみることはできません。
下のコマンドを実行するとみれるようになります。
php artisan storage:link
おわりに
この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。
最後まで読んでいただきありがとうございました!
参考