### Title: React Hooks by Example Part 2
### Description:
This article is the second part of a series that explores React hooks in depth through practical examples. In this installment, we will delve into more advanced use cases of React hooks such as `useReducer`, `useEffect`, and `useContext`. We'll also discuss how to manage state and side effects more effectively with these hooks.
### Content:
#### Introduction to React Hooks by Example Part 2
In the first part of our series on React Hooks, we introduced you to the basics of `useState` and `useEffect`. In this continuation, we'll explore more complex scenarios using `useReducer`, `useEffect`, and `useContext`.
#### Using `useReducer`
The `useReducer` hook is useful for managing state that can be divided into separate parts that can be dispatched independently. It's particularly handy when dealing with complex logic where multiple pieces of state need to be managed together.
**Example: Counter with Actions**
```jsx
import React, { useReducer } from 'react';
// Reducer function
function counterReducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
return (
<div>
<h2>Count: {state.count}</h2>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
}
```
#### Using `useEffect`
The `useEffect` hook allows you to perform side effects like fetching data or updating the DOM after the component mounts or unmounts. This is useful for handling subscriptions and cleanup logic.
**Example: Fetching Data with `useEffect`**
```jsx
import React, { useEffect } from 'react';
function DataFetcher() {
useEffect(() => {
// Fetch data
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []); // Empty dependency array means it runs once on mount
const [data, setData] = useState([]);
return (
<div>
{data.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
);
}
```
#### Using `useContext`
The `useContext` hook provides a way to read values from a context provider. It’s useful for sharing global state across components without passing props down every level.
**Example: Creating a Context for Theme Management**
```jsx
import React, { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
function App() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<ThemeProvider>
<div className={`app ${theme}`}>
<Header />
<Content />
</div>
</ThemeProvider>
);
}
function Header() {
return (
<header>
<button onClick={() => setTheme('dark')}>Dark Mode</button>
</header>
);
}
function Content() {
return (
<div>
<p>This is the content.</p>
</div>
);
}
```
#### Conclusion
In this part of our series, we have explored `useReducer`, `useEffect`, and `useContext`. These hooks provide powerful ways to manage state and side effects in your React applications. By mastering these concepts, you’ll be able to write more maintainable and scalable code. Stay tuned for the next part where we’ll dive deeper into advanced topics and best practices.
This concludes our exploration of React Hooks by Example Part 2. If you have any questions or would like to see more examples, feel free to leave a comment below!