mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
`unstable_isUnrecognizedActionError` is a new API that lets user code
check if a server action call failed because the action id wasn't
recognized by the server. This usually happens as a result of version
skew between client and server.
Example usage:
```ts
try {
await myServerAction();
} catch (err) {
if (unstable_isUnrecognizedActionError(err)) {
// The client is from a different deployment than the server.
// Reloading the page will fix this mismatch.
window.alert("Please refresh the page and try again");
return;
}
}
```
It can also be used to create a special error boundary, like we do in
the tests added here.
Note that this API is not a complete solution to this problem, as it
doesn't allow handling failures for MPA actions (sent without JS). We
might add a more complete API for this in the future to address that.
67 lines
1.6 KiB
TypeScript
67 lines
1.6 KiB
TypeScript
'use client'
|
|
import * as React from 'react'
|
|
import { useActionState } from 'react'
|
|
import { unstable_isUnrecognizedActionError as isUnrecognizedActionError } from 'next/navigation'
|
|
|
|
export function FormWithArg<T>({
|
|
action,
|
|
argument,
|
|
id,
|
|
children,
|
|
}: {
|
|
action: (state: string, argument: T) => Promise<string>
|
|
argument: T
|
|
id: string
|
|
children?: React.ReactNode
|
|
}) {
|
|
const [state, dispatch] = useActionState(
|
|
// don't use `bind()`, we want to explicitly avoid getting a FormData argument
|
|
// because that always results in a FormData request
|
|
(state) => action(state, argument),
|
|
'initial-state'
|
|
)
|
|
return (
|
|
<form id={id} action={dispatch}>
|
|
<button type="submit">{children}</button>
|
|
<span className="form-state">{`${state}`}</span>
|
|
</form>
|
|
)
|
|
}
|
|
|
|
export function Form({
|
|
action,
|
|
}: {
|
|
action: (state: string, formData: FormData) => Promise<string>
|
|
}) {
|
|
const [state, dispatch] = useActionState(action, 'initial-state')
|
|
return (
|
|
<form action={dispatch} id="form-direct">
|
|
<button type="submit">Submit server form</button>
|
|
<span className="form-state">{`${state}`}</span>
|
|
</form>
|
|
)
|
|
}
|
|
|
|
export class UnrecognizedActionBoundary extends React.Component<{
|
|
children: React.ReactNode
|
|
}> {
|
|
state = { error: null }
|
|
static getDerivedStateFromError(error) {
|
|
if (isUnrecognizedActionError(error)) {
|
|
return { error }
|
|
} else {
|
|
throw error
|
|
}
|
|
}
|
|
render() {
|
|
if (this.state.error) {
|
|
return (
|
|
<div id="error-boundary">
|
|
Error boundary: {this.state.error.message}
|
|
</div>
|
|
)
|
|
}
|
|
return this.props.children
|
|
}
|
|
}
|