Prompt
Design React hooks with performance and maintainability in mind by following these key principles:
-
Minimize useEffect usage - Update values directly when possible instead of using effects. Effects should only be used for true side effects, not for derived state updates.
-
Use the latest ref pattern for hook options to avoid unnecessary re-renders and ensure proper memoization:
function useCustomHook(options: Options) {
const optionsRef = useRef(options);
useLayoutEffect(() => {
optionsRef.current = options;
});
// Access latest options in callbacks
const handleChange = useCallback(() => {
const currentOptions = optionsRef.current;
// ... use currentOptions
}, []); // No options dependency needed
}
- Prefer useMemo for complex operations over useCallback when dealing with dependencies:
// Better approach
const handleSearchChange = useMemo(
() => debounce((value: string) => {
// Handle search
}),
[]
);
// Clean up on unmount
useEffect(() => {
return () => handleSearchChange.cancel();
}, []);
- Consider state management alternatives before reaching for useEffect - often state updates can be handled directly in event handlers or through proper component composition.
These patterns help avoid common pitfalls like unnecessary re-renders, stale closures, and complex dependency arrays while maintaining clean, performant React code.