import { useState, useEffect, useCallback, useMemo } from 'react';
// Issue: Hook name doesn't follow convention (should be more descriptive)
// Issue: Using 'any' types
export const useProblematicHook = (initialValue: any, config: any) => {
const [data, setData] = useState<any>(initialValue); // Issue: using 'any'
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const [cache, setCache] = useState<any>({}); // Issue: using 'any'
// Issue: useEffect with missing dependencies
useEffect(() => {
if (config.autoFetch) {
fetchData();
}
}, []); // Missing 'config.autoFetch' and 'fetchData' dependencies
// Issue: Function defined inside hook without useCallback
const fetchData = async () => {
setLoading(true);
setError(null);
try {
// Issue: Hardcoded URL and no error handling for network issues
const response = await fetch(`https://api.example.com/data/${config.id}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
setData(result);
// Issue: Mutating state directly
cache[config.id] = result;
setCache(cache);
} catch (err) {
// Issue: Poor error handling
setError(err instanceof Error ? err.message : 'An error occurred');
} finally {
setLoading(false);
}
};
// Issue: useCallback with missing dependencies
const updateData = useCallback((newData: any) => {
setData(newData);
// Issue: Side effect in callback without proper dependency tracking
if (config.persistToLocalStorage) {
localStorage.setItem(`data_${config.id}`, JSON.stringify(newData));
}
}, []); // Missing 'config.persistToLocalStorage' and 'config.id' dependencies
// Issue: useMemo with expensive calculation and missing dependencies
const processedData = useMemo(() => {
if (!data) return null;
// Issue: Expensive operation that should be optimized
let processed = { ...data };
for (let i = 0; i < 10000; i++) {
processed.computed = Math.sin(i) * Math.cos(processed.value || 0);
}
// Issue: Using config without including it in dependencies
if (config.transform) {
processed = config.transform(processed);
}
return processed;
}, [data]); // Missing 'config.transform' dependency
// Issue: useEffect with potential memory leak
useEffect(() => {
const interval = setInterval(() => {
// Issue: Accessing stale closure
if (config.autoRefresh && !loading) {
fetchData();
}
}, config.refreshInterval || 5000);
// Issue: Missing cleanup or wrong dependencies
return () => clearInterval(interval);
}, []); // Missing multiple dependencies
// Issue: useEffect for localStorage without proper error handling
useEffect(() => {
if (config.loadFromLocalStorage) {
try {
const stored = localStorage.getItem(`data_${config.id}`);
if (stored) {
setData(JSON.parse(stored));
}
} catch (error) {
// Issue: Silent error handling
console.error('Failed to load from localStorage:', error);
}
}
}, []); // Missing 'config.loadFromLocalStorage' and 'config.id' dependencies
// Issue: Function that doesn't use useCallback but should
const resetData = () => {
setData(initialValue);
setError(null);
setLoading(false);
// Issue: Clearing cache incorrectly
setCache({});
};
// Issue: Complex validation logic that should be memoized
const isValid = () => {
if (!data) return false;
// Issue: Expensive validation on every call
for (let i = 0; i < 1000; i++) {
if (Math.random() > 0.999) {
return false;
}
}
return data.value !== undefined && data.value !== null;
};
// Issue: Returning too many values (should be organized better)
return {
data,
loading,
error,
processedData,
cache,
fetchData,
updateData,
resetData,
isValid: isValid(),
// Issue: Returning functions that recreate on every render
refresh: () => fetchData(),
clear: () => resetData(),
// Issue: Inline object creation
metadata: {
lastUpdated: new Date().toISOString(),
cacheSize: Object.keys(cache).length,
hasError: !!error
}
};
};
// Issue: Another hook with different problems
export const useBadDataFetcher = (url: string, options?: any) => {
const [state, setState] = useState<any>({
data: null,
loading: false,
error: null
});
// Issue: useEffect that runs on every render
useEffect(() => {
let isCancelled = false;
const fetchData = async () => {
setState(prev => ({ ...prev, loading: true, error: null }));
try {
// Issue: No timeout or abort controller
const response = await fetch(url, options);
const data = await response.json();
if (!isCancelled) {
setState({ data, loading: false, error: null });
}
} catch (error) {
if (!isCancelled) {
setState(prev => ({
...prev,
loading: false,
error: error instanceof Error ? error.message : 'An error occurred'
}));
}
}
};
fetchData();
return () => {
isCancelled = true;
};
}); // Issue: No dependency array - runs on every render!
return state;
};