diff options
author | 2024-07-30 11:04:10 -0400 | |
---|---|---|
committer | 2024-07-30 11:04:10 -0400 | |
commit | 84189b6511dc2a14bcfe608696f56a64c2046f39 (patch) | |
tree | bd55e078427f570f3198973d0f58705a05f49daa /packages/integrations/react | |
parent | 1953dbbd41d2d7803837601a9e192654f02275ef (diff) | |
download | astro-84189b6511dc2a14bcfe608696f56a64c2046f39.tar.gz astro-84189b6511dc2a14bcfe608696f56a64c2046f39.tar.zst astro-84189b6511dc2a14bcfe608696f56a64c2046f39.zip |
Actions: New fallback behavior with `action={actions.name}` (#11570)
* feat: support _astroAction query param
* feat(test): _astroAction query param
* fix: handle _actions requests from legacy fallback
* feat(e2e): new actions pattern on blog test
* feat: update React 19 adapter to use query params
* fix: remove legacy getApiContext()
* feat: ActionQueryStringInvalidError
* fix: update error description
* feat: ActionQueryStringInvalidError
* chore: comment on _actions skip
* feat: .queryString property
* chore: comment on throw new Error
* chore: better guess for "why" on query string
* chore: remove console log
* chore: changeset
* chore: changeset
Diffstat (limited to 'packages/integrations/react')
-rw-r--r-- | packages/integrations/react/server.js | 7 | ||||
-rw-r--r-- | packages/integrations/react/src/actions.ts | 5 |
2 files changed, 9 insertions, 3 deletions
diff --git a/packages/integrations/react/server.js b/packages/integrations/react/server.js index 59134a699..6624a5610 100644 --- a/packages/integrations/react/server.js +++ b/packages/integrations/react/server.js @@ -131,6 +131,7 @@ async function getFormState({ result }) { if (!actionResult) return undefined; if (!isFormRequest(request.headers.get('content-type'))) return undefined; + const { searchParams } = new URL(request.url); const formData = await request.clone().formData(); /** * The key generated by React to identify each `useActionState()` call. @@ -142,7 +143,11 @@ async function getFormState({ result }) { * This matches the endpoint path. * @example "/_actions/blog.like" */ - const actionName = formData.get('_astroAction')?.toString(); + const actionName = + searchParams.get('_astroAction') ?? + /* Legacy. TODO: remove for stable */ formData + .get('_astroAction') + ?.toString(); if (!actionKey || !actionName) return undefined; diff --git a/packages/integrations/react/src/actions.ts b/packages/integrations/react/src/actions.ts index 336d32220..bc45e28ee 100644 --- a/packages/integrations/react/src/actions.ts +++ b/packages/integrations/react/src/actions.ts @@ -25,8 +25,9 @@ export function experimental_withState<T>(action: FormFn<T>) { callback.$$FORM_ACTION = action.$$FORM_ACTION; // Called by React when form state is passed from the server. // If the action names match, React returns this state from `useActionState()`. - callback.$$IS_SIGNATURE_EQUAL = (actionName: string) => { - return action.toString() === actionName; + callback.$$IS_SIGNATURE_EQUAL = (incomingActionName: string) => { + const actionName = new URLSearchParams(action.toString()).get('_astroAction'); + return actionName === incomingActionName; }; // React calls `.bind()` internally to pass the initial state value. |