fix: corrigir hooks com dependências exaustivas

- magnet-lines: move useEffect antes do early return (hooks não podem
  ser chamados condicionalmente), adiciona disabled aos deps
- use-month-period: memoiza [...MONTH_NAMES] com useMemo
- lancamentos-filters: handleFilterChange em useCallback
- inbox-page: sortByTimestamp em useCallback, atualiza deps dos useMemo
- note-card: remove formattedDate não utilizado do useMemo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-02-26 17:23:37 +00:00
parent ac2ea63dbd
commit edd5b8627d
5 changed files with 43 additions and 30 deletions

View File

@@ -34,7 +34,7 @@ export function NoteCard({
onArquivar,
isArquivadas = false,
}: NoteCardProps) {
const { formattedDate, displayTitle } = useMemo(() => {
const { displayTitle } = useMemo(() => {
const resolvedTitle = note.title.trim().length
? note.title
: "Anotação sem título";

View File

@@ -6,7 +6,13 @@ import {
RiFilter3Line,
} from "@remixicon/react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { type ReactNode, useEffect, useState, useTransition } from "react";
import {
type ReactNode,
useCallback,
useEffect,
useState,
useTransition,
} from "react";
import { Button } from "@/components/ui/button";
import {
Command,
@@ -143,21 +149,24 @@ export function LancamentosFilters({
const getParamValue = (key: string) =>
searchParams.get(key) ?? FILTER_EMPTY_VALUE;
const handleFilterChange = (key: string, value: string | null) => {
const nextParams = new URLSearchParams(searchParams.toString());
const handleFilterChange = useCallback(
(key: string, value: string | null) => {
const nextParams = new URLSearchParams(searchParams.toString());
if (value && value !== FILTER_EMPTY_VALUE) {
nextParams.set(key, value);
} else {
nextParams.delete(key);
}
if (value && value !== FILTER_EMPTY_VALUE) {
nextParams.set(key, value);
} else {
nextParams.delete(key);
}
startTransition(() => {
router.replace(`${pathname}?${nextParams.toString()}`, {
scroll: false,
startTransition(() => {
router.replace(`${pathname}?${nextParams.toString()}`, {
scroll: false,
});
});
});
};
},
[searchParams, pathname, router],
);
const [searchValue, setSearchValue] = useState(searchParams.get("q") ?? "");
const currentSearchParam = searchParams.get("q") ?? "";

View File

@@ -30,12 +30,8 @@ const MagnetLines: React.FC<MagnetLinesProps> = ({
}) => {
const containerRef = useRef<HTMLDivElement | null>(null);
// Se magnetlines estiver desabilitado, não renderiza nada
if (disabled) {
return null;
}
useEffect(() => {
if (disabled) return;
const container = containerRef.current;
if (!container) return;
@@ -72,7 +68,12 @@ const MagnetLines: React.FC<MagnetLinesProps> = ({
return () => {
window.removeEventListener("pointermove", handlePointerMove);
};
}, []);
}, [disabled]);
// Se magnetlines estiver desabilitado, não renderiza nada
if (disabled) {
return null;
}
const total = rows * columns;
const spans = Array.from({ length: total }, (_, i) => (

View File

@@ -52,24 +52,27 @@ export function InboxPage({
const [discardOpen, setDiscardOpen] = useState(false);
const [itemToDiscard, setItemToDiscard] = useState<InboxItem | null>(null);
const sortByTimestamp = (list: InboxItem[]) =>
[...list].sort(
(a, b) =>
new Date(b.notificationTimestamp).getTime() -
new Date(a.notificationTimestamp).getTime(),
);
const sortByTimestamp = useCallback(
(list: InboxItem[]) =>
[...list].sort(
(a, b) =>
new Date(b.notificationTimestamp).getTime() -
new Date(a.notificationTimestamp).getTime(),
),
[],
);
const sortedPending = useMemo(
() => sortByTimestamp(pendingItems),
[pendingItems],
[pendingItems, sortByTimestamp],
);
const sortedProcessed = useMemo(
() => sortByTimestamp(processedItems),
[processedItems],
[processedItems, sortByTimestamp],
);
const sortedDiscarded = useMemo(
() => sortByTimestamp(discardedItems),
[discardedItems],
[discardedItems, sortByTimestamp],
);
const handleProcessOpenChange = useCallback((open: boolean) => {