Memo

メモ > 技術 > フレームワーク: 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']);

Advertisement