🚀 8 Advanced React Features You Must Know in 2025
React has grown a lot since its early days. Beyond state, props, and hooks, React 18 introduced powerful advanced features that make apps more responsive, resilient, and scalable.
If you’re aiming to level up your React skills, understanding these features is a must.
In this blog, we’ll explore 8 advanced React features with definitions, explanations, and code examples.
1. ⚡ Concurrent Rendering (React 18)
Definition
Concurrent Rendering in React 18 allows React to prepare multiple versions of the UI simultaneously without blocking the main thread.
Explanation
- Makes rendering interruptible and non-blocking.
- Keeps the UI responsive during heavy updates.
- Enabled by default in React 18 with features like
startTransitionanduseDeferredValue.
Example
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(c => c + 1)}>Increase</button>
<p>Count: {count}</p>
</div>
);
}
👉 In React 18, even with expensive components, rendering can be interrupted so urgent updates like user input remain smooth.
2. ⏳ Transitions → useTransition
Definition
useTransition marks updates as non-urgent, allowing React to prioritize urgent updates (like typing) first.
Explanation
- Perfect for cases like search + filtering large lists.
- Keeps typing smooth while running heavy computations.
Example
import { useState, useTransition } from "react";
function Search() {
const [query, setQuery] = useState("");
const [list, setList] = useState([]);
const [isPending, startTransition] = useTransition();
function handleChange(e) {
const value = e.target.value;
setQuery(value);
startTransition(() => {
const results = Array.from({ length: 10000 }, (_, i) => `Item ${i}`)
.filter(item => item.includes(value));
setList(results);
});
}
return (
<div>
<input value={query} onChange={handleChange} placeholder="Search..." />
{isPending && <p>Loading...</p>}
<ul>{list.map((item, i) => <li key={i}>{item}</li>)}</ul>
</div>
);
}
👉 useTransition ensures typing stays smooth, even while filtering thousands of items.
3. 🕒 useDeferredValue → Handling Slow Computations
Definition
useDeferredValue defers updating a value, letting React keep the UI responsive.
Explanation
- Similar to
useTransition, but works on values instead of updates. - Useful for heavy rendering after input changes.
Example
import { useState, useDeferredValue } from "react";
function Search() {
const [query, setQuery] = useState("");
const deferredQuery = useDeferredValue(query);
const results = Array.from({ length: 5000 }, (_, i) => `Item ${i}`)
.filter(item => item.includes(deferredQuery));
return (
<div>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
<ul>{results.map((item, i) => <li key={i}>{item}</li>)}</ul>
</div>
);
}
👉 The input updates instantly, while results update slightly later, avoiding UI freezes.
4. 🎭 Suspense for Data Fetching
Definition
Suspense lets React wait for data before rendering a component, showing a fallback UI meanwhile.
Explanation
- First used for code-splitting, now extended to data fetching (Next.js, React Query, etc.).
- Enables streaming UI rendering.
Example
import React, { Suspense } from "react";
const UserProfile = React.lazy(() => import("./UserProfile"));
function App() {
return (
<Suspense fallback={<p>Loading profile...</p>}>
<UserProfile />
</Suspense>
);
}
👉 With SSR + streaming, React can render parts of the UI while other parts are still loading.
5. 🛑 Error Boundaries
Definition
Error Boundaries are React components that catch errors in child components and display a fallback UI.
Explanation
- Works only in class components.
- Doesn’t catch errors in event handlers or async code.
Example
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error, info) {
console.error("Error:", error, info);
}
render() {
if (this.state.hasError) {
return <h2>Something went wrong.</h2>;
}
return this.props.children;
}
}
function BuggyComponent() {
throw new Error("Crashed!");
}
function App() {
return (
<ErrorBoundary>
<BuggyComponent />
</ErrorBoundary>
);
}
👉 Prevents app crashes by showing a fallback UI.
6. 🪟 Portals → Rendering Outside Parent Hierarchy
Definition
Portals let you render children into a DOM node outside their parent hierarchy.
Explanation
- Ideal for modals, tooltips, dropdowns.
- Breaks out of CSS/DOM constraints.
Example
import ReactDOM from "react-dom";
function Modal({ children }) {
return ReactDOM.createPortal(
<div className="modal">{children}</div>,
document.getElementById("modal-root")
);
}
function App() {
return (
<div>
<h1>Main App</h1>
<Modal>
<p>This is inside a portal!</p>
</Modal>
</div>
);
}
👉 Even though Modal is inside App, it renders into #modal-root.
7. 🎯 Forwarding Refs → React.forwardRef
Definition
Forwarding refs allows parent components to pass refs down to child components.
Explanation
- Crucial for reusable UI components (like custom inputs).
- Lets parents control child elements directly.
Example
const CustomInput = React.forwardRef((props, ref) => (
<input ref={ref} {...props} />
));
function App() {
const inputRef = React.useRef();
return (
<div>
<CustomInput ref={inputRef} placeholder="Type here..." />
<button onClick={() => inputRef.current.focus()}>Focus Input</button>
</div>
);
}
👉 Now the parent can directly control the input focus.
8. 🔍 StrictMode Behaviors
Definition
StrictMode is a development-only feature that helps identify potential issues in your React app.
Explanation
- Runs some lifecycle methods twice (in dev).
- Warns about deprecated APIs.
- Ensures your app is ready for concurrent rendering.
Example
function App() {
return (
<React.StrictMode>
<MyComponent />
</React.StrictMode>
);
}
👉 Don’t panic if useEffect runs twice — it’s just for debugging.
🎯 Final Thoughts
React keeps evolving, and mastering these advanced features helps you build faster, resilient, and scalable apps:
✅ Concurrent Rendering → Keeps UI responsive
✅ useTransition & useDeferredValue → Smooth heavy updates
✅ Suspense → Elegant async handling
✅ Error Boundaries → Prevent crashes
✅ Portals → Flexible modals/tooltips
✅ Forwarding Refs → Reusable UI components
✅ StrictMode → Catch bugs early
Comments
Post a Comment