I'm building a Laravel and Vue.js SPA using Inertia.js. When I initially rendered the todos directly in the Home page, data updates on newly created todos. However, after introducing a TodoList component to handle the rendering, the data doesn't update as expected after adding a new todo (unless with a manual page reload). The TodoList component receives the todos prop but doesn't reactively update when new data is available.
Here are code the code snippets:
web.php:
Route::get('/', [TodoController::class, 'index'])->name('index');
Route::apiResource('todos', TodoController::class);
todoController.php:
class TodoController extends Controller
{
//
public function index()
{
return Inertia::render('Home', [
'todos' => Todo::latest()->get()->toArray(),
]);
}
public function store(Request $request)
{
Todo::create([
'task' => $request->input('task'),
]);
return redirect()->to('/');
}
}
Home.vue:
<template>
<TodoList :todos="todos" />
</template>
<script setup>
import TodoList from "./TodoList.vue";
defineProps(["todos"]);
</script>
TodoList.vue:
<template>
<div class="w-2/3 flex flex-col justify-center">
<Todo v-for="todo in todos" :todo="todo" />
</div>
</template>
<script setup>
import Todo from "./Todo.vue";
defineProps(["todos"]);
</script>
Todo.vue:
<template>
<form @submit.prevent="addTodo" class="relative">
<input
class="p-3 pr-12 w-full rounded-md"
type="text"
name="todo"
id="todo"
placeholder="Create a new todo..."
v-model="todoForm.task"
/>
<button
class="absolute text-white flex justify-center items-center top-1 right-1"
>
<span
class="text-white bg-indigo-600 rounded-full text-5xl h-10 w-10 leading-[30px]"
>+</span
>
</button>
</form>
</template>
<script setup>
import { useForm } from "@inertiajs/vue3";
const todoForm = useForm({
task: "",
});
const addTodo = () => {
todoForm.post("/todos", {
onSuccess: () => {
todoForm.reset("task");
},
});
};
</script>
I tried wrapping the todos being passed as props with "ref" reactivity api, no results.