1.
Introduction to Hooks
What are Hooks? Hooks are functions that let you use React features (like state and lifecycle)
in functional components. Introduced in React 16.8, they allow developers to avoid class
components while keeping the same functionality.
Why Hooks?
o Simplify code by reducing boilerplate.
o Enhance readability and reusability of logic.
o Eliminate the need for class components.
o Improve testability of components.
Common Rules of Hooks:
1. Only call Hooks at the top level (not inside loops, conditions, or nested functions).
2. Only call Hooks from React functional components or custom Hooks.
2. useState: Managing Local State
Purpose: To manage local state in a functional component.
Syntax:
jsx
const [state, setState] = useState(initialValue);
Example:
jsx
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
Key Points:
o useState returns an array with two elements: the current state and a function to
update it.
o State updates through setState trigger re-renders.
3. useEffect: Managing Side-Effects
Purpose: To handle side-effects like data fetching, subscriptions, and DOM manipulations.
Syntax:
jsx
useEffect(() => {
// Effect logic here
return () => {
// Cleanup logic here (optional)
};
}, [dependencies]);
Example:
jsx
Copy code
import React, { useEffect, useState } from 'react';
function DataFetcher() {
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
return () => console.log('Cleanup on component unmount');
}, []);
return <ul>{data.map(item => <li key={item.id}>{item.name}</li>)}</ul>;
}
Key Points:
o The second argument (dependency array) determines when the effect runs.
o An empty array ([]) makes the effect run only once (on mount).
4. useRef: Accessing DOM Elements and Component Instances
Purpose: To access and manipulate DOM nodes or persist a value across renders without
triggering re-renders.
Syntax:
jsx
const ref = useRef(initialValue);
Example:
jsx
import React, { useRef } from 'react';
function TextInput() {
const inputRef = useRef();
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus Input</button>
</div>
);
Key Points:
o The ref object persists across renders.
o useRef does not notify when its value changes.
5. useReducer: Handling Complex State Logic
Purpose: To manage complex state logic, often as an alternative to useState.
Syntax:
jsx
const [state, dispatch] = useReducer(reducer, initialState);
Example:
jsx
Copy code
import React, { useReducer } from 'react';
const initialState = { count: 0 };
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
};
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
Key Points:
o Use for complex state logic or when the next state depends on the previous state.
6. useContext: Context API for State Sharing
Purpose: To share state or props globally without prop drilling.
Syntax:
jsx
Copy code
const value = useContext(MyContext);
Example:
jsx
Copy code
import React, { useContext, createContext } from 'react';
const ThemeContext = createContext();
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ backgroundColor: theme }}>Click me</button>;
function App() {
return (
<ThemeContext.Provider value="blue">
<ThemedButton />
</ThemeContext.Provider>
);
}
Key Points:
o Simplifies consuming context values.
o Works seamlessly with the Context API.
7. Custom Hooks
Purpose: To encapsulate and reuse stateful logic across components.
Syntax:
jsx
function useCustomHook() {
// Logic here
return value;
Example:
jsx
import React, { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
});
}, [url]);
return { data, loading };
}
function DataDisplay() {
const { data, loading } = useFetch('https://api.example.com/data');
if (loading) return <p>Loading...</p>;
return <ul>{data.map(item => <li key={item.id}>{item.name}</li>)}</ul>;
Key Points:
o Start custom Hooks with the prefix use.
o Combine multiple built-in Hooks to create reusable logic.