Skip to content

Commit a41e867

Browse files
feat: Export useHydrated hook with documentation (#5645)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 941e4e7 commit a41e867

File tree

6 files changed

+53
-4
lines changed

6 files changed

+53
-4
lines changed

docs/start/framework/react/guide/execution-model.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,31 @@ function Analytics() {
9898
}
9999
```
100100

101+
#### useHydrated Hook
102+
103+
For more granular control over hydration-dependent behavior, use the `useHydrated` hook. It returns a boolean indicating whether the client has been hydrated:
104+
105+
```tsx
106+
import { useHydrated } from '@tanstack/react-router'
107+
108+
function TimeZoneDisplay() {
109+
const hydrated = useHydrated()
110+
const timeZone = hydrated
111+
? Intl.DateTimeFormat().resolvedOptions().timeZone
112+
: 'UTC'
113+
114+
return <div>Your timezone: {timeZone}</div>
115+
}
116+
```
117+
118+
**Behavior:**
119+
120+
- **During SSR**: Always returns `false`
121+
- **First client render**: Returns `false`
122+
- **After hydration**: Returns `true` (and stays `true` for all subsequent renders)
123+
124+
This is useful when you need to conditionally render content based on client-side data (like browser timezone, locale, or localStorage) while providing a sensible fallback for server rendering.
125+
101126
### Environment-Specific Implementations
102127

103128
```tsx

docs/start/framework/solid/guide/execution-model.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,30 @@ function Analytics() {
9898
}
9999
```
100100

101+
#### useHydrated Hook
102+
103+
For more granular control over hydration-dependent behavior, use the `useHydrated` hook. It returns an accessor (signal) indicating whether the client has been hydrated:
104+
105+
```tsx
106+
import { useHydrated } from '@tanstack/solid-router'
107+
108+
function TimeZoneDisplay() {
109+
const hydrated = useHydrated()
110+
const timeZone = () =>
111+
hydrated() ? Intl.DateTimeFormat().resolvedOptions().timeZone : 'UTC'
112+
113+
return <div>Your timezone: {timeZone()}</div>
114+
}
115+
```
116+
117+
**Behavior:**
118+
119+
- **During SSR**: Always returns `false`
120+
- **First client render**: Returns `false`
121+
- **After hydration**: Returns `true` (and stays `true` for all subsequent renders)
122+
123+
This is useful when you need to conditionally render content based on client-side data (like browser timezone, locale, or localStorage) while providing a sensible fallback for server rendering.
124+
101125
### Environment-Specific Implementations
102126

103127
```tsx

packages/react-router/src/ClientOnly.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export function ClientOnly({ children, fallback = null }: ClientOnlyProps) {
6363
/**
6464
* Return a boolean indicating whether client hydration has occurred.
6565
*/
66-
function useHydrated(): boolean {
66+
export function useHydrated(): boolean {
6767
return React.useSyncExternalStore(
6868
subscribe,
6969
() => true,

packages/react-router/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export { useAwaited, Await } from './awaited'
130130
export type { AwaitOptions } from './awaited'
131131

132132
export { CatchBoundary, ErrorComponent } from './CatchBoundary'
133-
export { ClientOnly } from './ClientOnly'
133+
export { ClientOnly, useHydrated } from './ClientOnly'
134134

135135
export {
136136
FileRoute,

packages/solid-router/src/ClientOnly.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export function ClientOnly(props: ClientOnlyProps) {
5656
* ```
5757
* @returns True if the JS has been hydrated already, false otherwise.
5858
*/
59-
function useHydrated(): Solid.Accessor<boolean> {
59+
export function useHydrated(): Solid.Accessor<boolean> {
6060
const [hydrated, setHydrated] = Solid.createSignal(false)
6161
Solid.onMount(() => {
6262
setHydrated(true)

packages/solid-router/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ export { useAwaited, Await } from './awaited'
211211
export type { AwaitOptions } from './awaited'
212212

213213
export { CatchBoundary, ErrorComponent } from './CatchBoundary'
214-
export { ClientOnly } from './ClientOnly'
214+
export { ClientOnly, useHydrated } from './ClientOnly'
215215

216216
export {
217217
FileRoute,

0 commit comments

Comments
 (0)