useIsClient vs useIsMounted
tip
useIsClient
is primarily for handling SSR scenarios, while useIsMounted
is for managing component lifecycle and preventing memory leaks or updates after unmounting.
Timing and Purposeโ
useIsClient
specifically tells you if the code is running in a browser vs server environmentuseIsMounted
tells you if a component is currently mounted in the DOM
Implementationโ
useIsClient
usesuseState
directly and only sets totrue
onceuseIsMounted
usesuseRef
and returns a callback function that checks the ref
Return Value
useIsClient
returns a boolean directlyuseIsMounted
returns a function that returns a boolean
Here are scenarios where they would differ:
function Example() {
const isClient = useIsClient()
const isMounted = useIsMounted()
// Scenario 1: Initial Server-Side Rendering
console.log(isClient) // false during SSR, true after hydration
console.log(isMounted()) // true in both cases
// Scenario 2: Component Unmounting
useEffect(() => {
const timer = setTimeout(() => {
console.log(isClient) // true (doesn't change)
console.log(isMounted()) // false (component unmounted)
}, 1000)
return () => clearTimeout(timer)
}, [])
return null
}
Server-Side Renderingโ
useIsClient
will befalse
during SSR and initial render, thentrue
after hydrationuseIsMounted
will betrue
as soon as the component mounts, regardless of SSR
Component Lifecycleโ
useIsClient
staystrue
once set, even if the component unmountsuseIsMounted
becomesfalse
when the component unmounts
Race Conditionsโ
useIsClient
is better for conditional rendering based on client/server environmentuseIsMounted
is better for preventing state updates after unmounting
// Example where `useIsMounted` is more appropriate
function DataFetcher() {
const isMounted = useIsMounted()
useEffect(() => {
fetchData().then((data) => {
// Prevents memory leak and updates after unmount
if (isMounted()) {
setData(data)
}
})
}, [])
}
// Example where `useIsClient` is more appropriate
function BrowserFeature() {
const isClient = useIsClient()
// Only renders browser-specific features after hydration
return isClient ? <WindowSizeDisplay /> : null
}