React is ever-evolving—and while most devs know the basics (hooks, JSX, props, etc.), there are some next-level tricks hiding in plain sight. Whether you're a React veteran or someone who lives in hooks, this post dives into tips that even seasoned pros might not be using.
useRef
Is More Than DOM ReferencesMost people use useRef
just to access DOM elements. But it’s also a great way to store mutable values without triggering re-renders.
const renderCount = useRef(0);
renderCount.current++;
Use it to track things like previous values, timers, or render counts without causing re-renders.
Code splitting isn't just for routes! Use React.lazy()
to lazily load any component:
const HeroBanner = React.lazy(() => import('./HeroBanner'));
Wrap it in a <Suspense>
and you’re good to go. Perfect for dashboards, modals, or feature-heavy components.
useEffect
Cleanup Is Your Secret WeaponYour cleanup functions can be used for more than unsubscribing. They're great for resetting state, cancelling async calls, or even animations:
useEffect(() => {
const timer = setTimeout(() => {
setShowMessage(true);
}, 3000);
return () => clearTimeout(timer); // prevents memory leaks
}, []);
Instead of this:
function Button(props) {
return <button>{props.label}</button>;
}
Do this:
function Button({ label }) {
return <button>{label}</button>;
}
It’s cleaner, easier to read, and scales better.
useCallback
and useMemo
for RealReact pros know useCallback
and useMemo
, but few use them properly. Use them only when:
Otherwise, they may actually slow things down.
Did you know you can use hover/focus styles in inline objects?
const styles = {
button: {
padding: '10px',
':hover': {
backgroundColor: 'lightblue',
},
},
};
Use it with Emotion or styled-components' object syntax for dynamic theming or modes.
For faster-feeling apps:
const [liked, setLiked] = useState(false);
const handleLike = () => {
setLiked(true); // update immediately
api.likePost(postId); // update in background
};
Always update UI first, then sync with server. If needed, rollback on error.
useEffect
DependenciesInstead of manually tracking dependencies, wrap logic in custom hooks.
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handler = () => setWidth(window.innerWidth);
window.addEventListener('resize', handler);
return () => window.removeEventListener('resize', handler);
}, []);
return width;
}
You now have clean, reusable logic without re-calculating every render.
React.memo
+ useCallback
= BulletproofIf you’re building heavy UIs, pair React.memo()
with stable props:
const ExpensiveComponent = React.memo(({ onClick }) => {
console.log("rendered");
return <button onClick={onClick}>Click me</button>;
});
const Parent = () => {
const handleClick = useCallback(() => {}, []);
return <ExpensiveComponent onClick={handleClick} />;
};
This avoids unnecessary re-renders like a charm.
Turn repeating patterns into custom hooks. Not only for clarity—but also for testability and scalability.
function useToggle(initial = false) {
const [value, setValue] = useState(initial);
const toggle = () => setValue((v) => !v);
return [value, toggle];
}
Then use it anywhere:
const [open, toggleOpen] = useToggle();
React is not about clever code—it's about predictable, maintainable UI. The best trick isn't a new hook—it's writing clean, readable code your future self (or teammate) will thank you for.
Got a killer React tip we didn’t mention? Drop it in the comments or share this post with your dev squad.
"The biggest benefit of React is how it forces you to think about your UI as a function of state. Once you embrace that, everything else falls into place."
- Dan Abramov, co-author of Redux & React team member
1 comment on this post
Chidera
April 16, 2025wow full of insight