I was using useEffect for every API call in React. It worked. But it was a mess. 😅 This is what my code looked like: const UserList = () => { const [users, setUsers] = useState([]) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) useEffect(() => { setLoading(true) fetchUsers() .then(data => setUsers(data)) .catch(err => setError(err)) .finally(() => setLoading(false)) }, []) if (loading) return <div>Loading...</div> if (error) return <div>Error!</div> return users.map(user => <UserCard user={user} />) } 3 useState calls. Manual loading/error handling. No caching. No refetching. Code repeated in every component. 😔 Then I discovered React Query: const UserList = () => { const { data, isLoading, error } = useQuery({ queryKey: ['users'], queryFn: fetchUsers }) if (isLoading) return <div>Loading...</div> if (error) return <div>Error!</div> return data.map(user => <UserCard user={user} />) } Same result. But: ✅ No manual loading state ✅ No manual error handling ✅ Automatic caching ✅ Background refetching ✅ 70% less code Rule I follow now: → Server state = React Query → UI state = useState → Complex state = useReducer Wish I knew this earlier. 🚀 Are you still using useEffect for API calls? Comment below! 👇 #ReactJS #JavaScript #Frontend #WebDevelopment #ReactQuery #CleanCode
😮 👏
I love using TanStack Query, really a lot less code to write and works very well in a lot of cases that you need. Refresh of stale data, auto retry, errors and loading state, definitely a wonderful package