React Hooks Deep Dive: useEffect and useState
Introduction
React Hooks allow you to use state and lifecycle features in functional components. In this tutorial, we'll dive deep into useEffect and useState, exploring common patterns and best practices.
useState
The useState hook lets you add state to functional components. Here's a simple example:
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
useEffect
The useEffect hook is used for side effects. It runs after render. Here's an example that fetches data:
import { useEffect, useState } from 'react';
function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => setUsers(data));
}, []); // Empty dependency array means run once on mount
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
Common Patterns
Fetching Data
- Use an empty dependency array
[]to run the effect only once on mount. - Handle loading and error states with additional state variables.
Updating State Based on Previous State
When updating state based on the previous state, use a functional update:
setCount(prev => prev + 1);
Cleanup in useEffect
If your effect involves subscriptions or timers, clean up in the return function:
useEffect(() => {
const timer = setInterval(() => console.log('tick'), 1000);
return () => clearInterval(timer);
}, []);
Conclusion
React Hooks provide a powerful way to manage state and side effects in functional components. By understanding useState and useEffect, you can build complex UIs with clean, readable code. Experiment with different patterns to find what works best for your application.
Top comments (0)