In React, a hook is a special function that allows you to use state and other React features in functional components. Prior to hooks, state and lifecycle methods were only available in class components. Hooks were introduced in React 16.8 to allow functional components to manage state and side effects, making them more powerful and flexible.
Basic Concepts of Hooks
State Hook (useState
): Allows you to add state to functional components.
Effect Hook (useEffect
): Lets you perform side effects in function components.
Context Hook (useContext
): Lets you use context to pass data through the component tree without having to pass props down manually at every level.
Rules of Hooks
- Only call hooks at the top level: Don’t call hooks inside loops, conditions, or nested functions. This ensures hooks are called in the same order each time a component renders.
- Only call hooks from React functions: Call them from within React functional components or custom hooks, not regular JavaScript functions.
Benefits of Hooks
- Simpler Code: Functional components with hooks are generally simpler and easier to read than class components.
- Reusability: Hooks allow you to reuse stateful logic across multiple components.
- Better Organization: Hooks let you split one component into smaller functions based on what pieces are related (e.g., setting up a subscription or fetching data).
Basic Hooks
useState
The useState
hook lets you add state to a functional component. It returns an array with two elements: the current state value and a function to update it.
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>
);
}
export default Counter;
useEffect
The useEffect
hook lets you perform side effects in function components. It’s similar to lifecycle methods in class components (componentDidMount
, componentDidUpdate
, componentWillUnmount
).
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
// Update the count
console.log(`You clicked ${count} times`);
}, [count]); // Only re-run the effect if count changes
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
export default Example;
useContext
The useContext
hook in React allows you to consume context in a functional component without needing to wrap your component in a Consumer
component. This makes the code more concise and easier to read. Context provides a way to pass data through the component tree without having to pass props down manually at every level.
Creating and Using Context
- Create a Context: Use the
createContext
function to create a context. - Provide a Context Value: Use a
Provider
component to pass the context value to the tree. - Consume Context: Use the
useContext
hook to consume the context value in a functional component.
Step-by-Step Example
Step 1: Create a Context
First, create a context using the createContext
function.
import { createContext } from 'react';
// Create a context with 'light' as the default value
const ThemeContext = createContext('light');
export { ThemeContext };
Step 2: Provide a Context Value
Wrap your component tree with a Provider
component and pass the context value.
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { ThemeContext } from './ThemeContext';
ReactDOM.render(
<ThemeContext.Provider value="dark">
<App />
</ThemeContext.Provider>,
document.getElementById('root')
);
Step 3: Consume Context
Use the useContext
hook to consume the context value in a functional component.
//ThemedButton.jsx
import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme === 'dark' ? '#333' : '#fff' }}>Themed Button</button>;
}
export default ThemedButton;
App.jsx
import React from 'react';
import ThemedButton from './ThemedButton';
function App() {
return (
<div>
<ThemedButton />
</div>
);
}
export default App;