Skip to content

Commit

Permalink
Add unstable_useFlushEffects hook (#34117)
Browse files Browse the repository at this point in the history
Implements #30997 with some minor tweaks to the design:

* The hook is moved to Client Components (e.g. `pages/_app` instead of `pages/_document`). This was a silly oversight in the original design: the hook needs to be called during server prerendering.

* `useFlushEffects` instead of `useFlushEffect` as there isn't a particularly safe way to implement the singular semantics as a Client Component hook given the current implementation of server rendering.

---

Fixes #30997
  • Loading branch information
devknoll committed Feb 18, 2022
1 parent a52bd71 commit 944c734
Show file tree
Hide file tree
Showing 15 changed files with 492 additions and 157 deletions.
24 changes: 24 additions & 0 deletions errors/client-flush-effects.md
@@ -0,0 +1,24 @@
# `useFlushEffects` can not be called on the client

#### Why This Error Occurred

The `useFlushEffects` hook was executed while rendering a component on the client, or in another unsupported environment.

#### Possible Ways to Fix It

The `useFlushEffects` hook can only be called while _server rendering a client component_. As a best practice, we recommend creating a wrapper hook:

```jsx
// lib/use-style-libraries.js
import { useFlushEffects } from 'next/streaming'

export default function useStyleLibraries() {
if (typeof window === 'undefined') {
// eslint-disable-next-line react-hooks/rules-of-hooks
useFlushEffects([
/* ... */
])
}
/* ... */
}
```
8 changes: 8 additions & 0 deletions errors/manifest.json
Expand Up @@ -623,6 +623,14 @@
{
"title": "opening-an-issue",
"path": "/errors/opening-an-issue.md"
},
{
"title": "multiple-flush-effects",
"path": "/errors/multiple-flush-effects.md"
},
{
"title": "client-flush-effects",
"path": "/errors/client-flush-effects.md"
}
]
}
Expand Down
9 changes: 9 additions & 0 deletions errors/multiple-flush-effects.md
@@ -0,0 +1,9 @@
# The `useFlushEffects` hook cannot be used more than once.

#### Why This Error Occurred

The `useFlushEffects` hook is being used more than once while a page is being rendered.

#### Possible Ways to Fix It

The `useFlushEffects` hook should only be called inside the body of the `pages/_app` component, before returning any `<Suspense>` boundaries. Restructure your application to prevent extraneous calls.
1 change: 1 addition & 0 deletions packages/next/client/streaming/index.ts
@@ -1,2 +1,3 @@
export { useRefreshRoot as unstable_useRefreshRoot } from './refresh'
export { useWebVitalsReport as unstable_useWebVitalsReport } from './vitals'
export { useFlushEffects as unstable_useFlushEffects } from '../../shared/lib/flush-effects'
4 changes: 2 additions & 2 deletions packages/next/server/render-result.ts
@@ -1,9 +1,9 @@
import type { ServerResponse } from 'http'

export default class RenderResult {
_result: string | ReadableStream
_result: string | ReadableStream<Uint8Array>

constructor(response: string | ReadableStream) {
constructor(response: string | ReadableStream<Uint8Array>) {
this._result = response
}

Expand Down

0 comments on commit 944c734

Please sign in to comment.