diff --git a/apps/web/components/kanban-board.tsx b/apps/web/components/kanban-board.tsx index ae7f4af3b1..53e3e62906 100644 --- a/apps/web/components/kanban-board.tsx +++ b/apps/web/components/kanban-board.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useMemo, useState } from 'react'; +import { useMemo, useState, useSyncExternalStore } from 'react'; import { DndContext, DragEndEvent, @@ -73,13 +73,14 @@ export function KanbanBoard() { const [tasks, setTasks] = useState(initialTasks); const [isDialogOpen, setIsDialogOpen] = useState(false); const [activeTaskId, setActiveTaskId] = useState(null); - const [isMounted, setIsMounted] = useState(false); const [activeViewId, setActiveViewId] = useState('team'); const [editingTaskId, setEditingTaskId] = useState(null); - useEffect(() => { - setIsMounted(true); - }, []); + const isMounted = useSyncExternalStore( + () => () => {}, + () => true, + () => false + ); const sensors = useSensors( useSensor(PointerSensor, { @@ -188,6 +189,7 @@ export function KanbanBoard() { { setIsDialogOpen(open); diff --git a/apps/web/components/kanban-column.tsx b/apps/web/components/kanban-column.tsx index f00daf75ca..dc549dbcbc 100644 --- a/apps/web/components/kanban-column.tsx +++ b/apps/web/components/kanban-column.tsx @@ -42,7 +42,7 @@ export function KanbanColumn({ column, tasks, onEditTask }: KanbanColumnProps) { {/* Tasks */} -
+
{tasks.length === 0 ? (

No tasks yet

) : ( diff --git a/apps/web/components/task-create-dialog.tsx b/apps/web/components/task-create-dialog.tsx index c09e34741c..8469effd8b 100644 --- a/apps/web/components/task-create-dialog.tsx +++ b/apps/web/components/task-create-dialog.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useState, FormEvent } from 'react'; +import { useState, FormEvent } from 'react'; import { AlertDialog, AlertDialogContent, @@ -32,14 +32,8 @@ export function TaskCreateDialog({ initialValues, submitLabel = 'Create', }: TaskCreateDialogProps) { - const [title, setTitle] = useState(''); - const [description, setDescription] = useState(''); - - useEffect(() => { - if (!open) return; - setTitle(initialValues?.title ?? ''); - setDescription(initialValues?.description ?? ''); - }, [open, initialValues]); + const [title, setTitle] = useState(initialValues?.title ?? ''); + const [description, setDescription] = useState(initialValues?.description ?? ''); const handleSubmit = (e: FormEvent) => { e.preventDefault(); diff --git a/apps/web/components/theme-toggle.tsx b/apps/web/components/theme-toggle.tsx index 66b722e9ee..f58f70f71f 100644 --- a/apps/web/components/theme-toggle.tsx +++ b/apps/web/components/theme-toggle.tsx @@ -3,15 +3,15 @@ import { useTheme } from 'next-themes'; import { IconMoon, IconSun } from '@tabler/icons-react'; import { Button } from '@/components/ui/button'; -import { useEffect, useState } from 'react'; +import { useSyncExternalStore } from 'react'; export function ThemeToggle() { const { theme, setTheme } = useTheme(); - const [mounted, setMounted] = useState(false); - - useEffect(() => { - setMounted(true); - }, []); + const mounted = useSyncExternalStore( + () => () => {}, + () => true, + () => false + ); if (!mounted) { return null;