Files
openmonetis/hooks/use-controlled-state.ts
Felipe Coutinho a7f63fb77a refactor: migrate from ESLint to Biome and extract SQL queries to data.ts
- Replace ESLint with Biome for linting and formatting
- Configure Biome with tabs, double quotes, and organized imports
- Move all SQL/Drizzle queries from page.tsx files to data.ts files
- Create new data.ts files for: ajustes, dashboard, relatorios/categorias
- Update existing data.ts files: extrato, fatura (add lancamentos queries)
- Remove all drizzle-orm imports from page.tsx files
- Update README.md with new tooling info

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 13:15:37 +00:00

52 lines
1.5 KiB
TypeScript

import { useCallback, useEffect, useState } from "react";
/**
* Hook for managing controlled/uncontrolled state pattern
* Allows a component to work both in controlled and uncontrolled mode
*
* @param controlledValue - The controlled value (undefined for uncontrolled mode)
* @param defaultValue - Default value for uncontrolled mode
* @param onChange - Callback when value changes
* @returns Tuple of [currentValue, setValue]
*
* @example
* ```tsx
* function MyComponent({ value, onChange }) {
* const [internalValue, setValue] = useControlledState(value, false, onChange);
* // Works both as controlled and uncontrolled
* }
* ```
*/
export function useControlledState<T>(
controlledValue: T | undefined,
defaultValue: T,
onChange?: (value: T) => void,
): [T, (value: T) => void] {
const [internalValue, setInternalValue] = useState<T>(defaultValue);
// Sync internal value when controlled value changes
useEffect(() => {
if (controlledValue !== undefined) {
setInternalValue(controlledValue);
}
}, [controlledValue]);
// Use controlled value if provided, otherwise use internal value
const value = controlledValue !== undefined ? controlledValue : internalValue;
const setValue = useCallback(
(newValue: T) => {
// Update internal state if uncontrolled
if (controlledValue === undefined) {
setInternalValue(newValue);
}
// Always call onChange if provided
onChange?.(newValue);
},
[controlledValue, onChange],
);
return [value, setValue];
}