メモ > 技術 > フレームワーク: Laravel10 > Reactを使う(登録編集削除の実例)
Reactを使う(登録編集削除の実例)
■コントローラーの修正
app/Http/Controllers/TaskController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use App\Models\Task;
use Illuminate\Support\Facades\Redirect;
use Inertia\Inertia;
use Inertia\Response as InertiaResponse;
class TaskController extends Controller
{
public function index(): InertiaResponse
{
$tasks = Task::all();
return Inertia::render('Task/Index', [
'tasks' => $tasks,
]);
}
public function store(Request $request): RedirectResponse
{
Task::create($request->validate([
'name' => ['required', 'max:20'],
]));
return Redirect::route('task.index');
}
public function update(Request $request, Task $task): RedirectResponse
{
$task->update($request->validate([
'name' => ['required', 'max:20'],
]));
return Redirect::route('task.index');
}
public function destroy(Task $task): RedirectResponse
{
$task->delete();
return Redirect::route('task.index');
}
}
■ビューの修正
resources/js/Pages/Task/Index.jsx
import GuestLayout from '@/Layouts/GuestLayout';
import { Head, useForm } from "@inertiajs/react";
import { useState } from 'react';
function TaskForm({ submit, data, setData, errors, closeModal }) {
return (
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
<div className="bg-white p-6 rounded shadow-lg w-1/3">
<form onSubmit={submit} className="mb-4">
<div>
<label className="me-2">タスク</label>
<input
value={data.name}
onChange={e => setData('name', e.target.value)}
className="border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm mt-1 me-2"
/>
<button type="submit" className="items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 focus:bg-gray-700 active:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition ease-in-out duration-150">
保存
</button>
{errors.name && <div className="mt-2 text-red-600">{errors.name}</div>}
</div>
<button onClick={closeModal} type="button" className="mt-4 items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 focus:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 transition ease-in-out duration-150">
キャンセル
</button>
</form>
</div>
</div>
);
}
export default function TaskPage({ tasks }) {
const [showModal, setShowModal] = useState(false);
const [editingTask, setEditingTask] = useState(null);
const { data, setData, post, put, delete: destroy, errors, reset, clearErrors } = useForm({
name: ''
});
const startCreating = () => {
reset();
clearErrors();
setEditingTask(null);
setShowModal(true);
};
const startEditing = task => {
setData('name', task.name);
clearErrors();
setEditingTask(task);
setShowModal(true);
};
const closeModal = () => {
setShowModal(false);
clearErrors();
};
const submitCreate = e => {
e.preventDefault();
post('/task/store', {
onSuccess: () => {
reset();
closeModal();
}
});
};
const submitEdit = e => {
e.preventDefault();
if (editingTask) {
put(`/task/update/${editingTask.id}`, {
onSuccess: () => {
reset();
closeModal();
}
});
}
};
const submitDelete = task => {
destroy(`/task/destroy/${task.id}`, {
onSuccess: () => reset()
});
};
return (
<GuestLayout>
<Head title="Task" />
<div>
<h2 className="font-semibold text-xl text-gray-800 leading-tight pb-4">Tasks</h2>
<button
onClick={startCreating}
className="items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 focus:bg-gray-700 active:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition ease-in-out duration-150 mb-4"
>
登録
</button>
{showModal && (
<TaskForm
submit={editingTask ? submitEdit : submitCreate}
data={data}
setData={setData}
errors={errors}
closeModal={closeModal}
/>
)}
<ul>
{tasks.map(task => (
<li key={task.id} className="mb-2">
{task.id}: {task.name}
<button
onClick={() => startEditing(task)}
className="ms-4 items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 focus:bg-gray-700 active:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition ease-in-out duration-150"
>
編集
</button>
<button
onClick={() => submitDelete(task)}
className="ms-2 items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 focus:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 transition ease-in-out duration-150"
>
削除
</button>
</li>
))}
</ul>
</div>
</GuestLayout>
);
}
■ルーティングの修正
routes/web.php
Route::get('/task', [TaskController::class, 'index'])->name('task.index');
Route::post('/task/store', [TaskController::class, 'store']);
Route::put('/task/update/{task}', [TaskController::class, 'update']);
Route::delete('/task/destroy/{task}', [TaskController::class, 'destroy']);