Advanced Patterns with Hooks in React
1. Introduction
React Hooks provide a way to use state and lifecycle features in functional components. Advanced patterns with hooks allow developers to create reusable components and manage complex states more elegantly.
2. Custom Hooks
Custom Hooks are JavaScript functions that can call other hooks. They allow you to extract component logic into reusable functions.
Creating a Custom Hook
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
setError(error);
setLoading(false);
});
}, [url]);
return { data, loading, error };
}
Using the Custom Hook
function App() {
const { data, loading, error } = useFetch('https://api.example.com/data');
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>{JSON.stringify(data)}</div>;
}
3. Compound Components
Compound components are components that work together. They allow for more flexible component composition.
const Accordion = ({ children }) => {
const [openIndex, setOpenIndex] = useState(0);
const toggle = index => {
setOpenIndex(openIndex === index ? null : index);
};
return (
<div>
{React.Children.map(children, (child, index) =>
React.cloneElement(child, { isOpen: openIndex === index, toggle: () => toggle(index) })
)}
</div>
);
};
const AccordionItem = ({ isOpen, toggle, children }) => (
<div onClick={toggle}>
<h2>{children}</h2>
{isOpen && <p>Content here</p>}
</div>
);
Using the Accordion
<Accordion>
<AccordionItem>Item 1</AccordionItem>
<AccordionItem>Item 2</AccordionItem>
<AccordionItem>Item 3</AccordionItem>
</Accordion>
4. Render Props
Render props is a technique for sharing code between React components using a prop that is a function.
const DataFetcher = ({ render }) => {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []);
return render(data);
};
Using Render Props
<DataFetcher render={data => (data ? <div>{JSON.stringify(data)}</div> : <span>Loading...</span>)} />
5. Using Context API
The Context API allows you to share values between components without having to explicitly pass props through every level of the tree.
const ThemeContext = React.createContext();
const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
};
Using the Context
const ThemedComponent = () => {
const { theme } = useContext(ThemeContext);
return <div className={theme}>This is the {theme} theme</div>;
};
6. FAQ
What are Hooks in React?
Hooks are functions that let you use state and other React features in functional components.
Can I use Hooks in class components?
No, Hooks can only be used in functional components.
What is a Custom Hook?
A Custom Hook is a JavaScript function whose name starts with "use" and can call other hooks inside it.