fix(CQ-WEB-2): Fix missing dependency in FilterBar useEffect
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

The debounced search useEffect accessed `filters` and `onFilterChange`
without including them in the dependency array. Fixed by:
- Using useRef for onFilterChange to maintain a stable reference
- Using functional state update (setFilters callback) to access
  previous filters without needing it as a dependency

This prevents stale closures while avoiding infinite re-render loops
that would occur if these values were added directly to the dep array.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jason Woltje
2026-02-06 13:11:49 -06:00
parent 76ac113d0c
commit 2c49371102
2 changed files with 25 additions and 10 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import { useState, useEffect, useCallback } from "react";
import { useState, useEffect, useCallback, useRef } from "react";
import { TaskStatus, TaskPriority } from "@mosaic/shared";
export interface FilterValues {
@@ -29,19 +29,28 @@ export function FilterBar({
const [showStatusDropdown, setShowStatusDropdown] = useState(false);
const [showPriorityDropdown, setShowPriorityDropdown] = useState(false);
// Stable ref for onFilterChange to avoid re-triggering the debounce effect
const onFilterChangeRef = useRef(onFilterChange);
useEffect(() => {
onFilterChangeRef.current = onFilterChange;
}, [onFilterChange]);
// Debounced search
useEffect(() => {
const timer = setTimeout(() => {
if (searchValue !== filters.search) {
const newFilters = { ...filters };
if (searchValue) {
newFilters.search = searchValue;
} else {
delete newFilters.search;
setFilters((prevFilters) => {
if (searchValue !== prevFilters.search) {
const newFilters = { ...prevFilters };
if (searchValue) {
newFilters.search = searchValue;
} else {
delete newFilters.search;
}
onFilterChangeRef.current(newFilters);
return newFilters;
}
setFilters(newFilters);
onFilterChange(newFilters);
}
return prevFilters;
});
}, debounceMs);
return (): void => {