Skip to content

Commit

Permalink
Scaffolding for useFormState (#27270)
Browse files Browse the repository at this point in the history
This exposes, but does not yet implement, a new experimental API called
useFormState. It's gated behind the enableAsyncActions flag.

useFormState has a similar signature to useReducer, except instead of a
reducer it accepts an (async) action function. React will wait until the
promise resolves before updating the state:

```js
async function action(prevState, payload) {
  // ..
}
const [state, dispatch] = useFormState(action, initialState)
```

When used in combination with Server Actions, it will also support
progressive enhancement — a form that is submitted before it has
hydrated will have its state transferred to the next page. However, like
the other action-related hooks, it works with fully client-driven
actions, too.

DiffTrain build for [b4cdd3e](b4cdd3e)
  • Loading branch information
acdlite committed Aug 23, 2023
1 parent ff6e098 commit 2bd9065
Show file tree
Hide file tree
Showing 21 changed files with 134 additions and 35 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
31034b6de73c7cd9093e92a34e384d84c082aa4e
b4cdd3e8922713f8c9817b004a0dc51be47bc5df
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if (
}
"use strict";

var ReactVersion = "18.3.0-www-modern-a61c0c27";
var ReactVersion = "18.3.0-www-modern-fd93b451";

// ATTENTION
// When adding new symbols to this file,
Expand Down
2 changes: 1 addition & 1 deletion compiled/facebook-www/ReactART-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function _assertThisInitialized(self) {
return self;
}

var ReactVersion = "18.3.0-www-modern-293df28d";
var ReactVersion = "18.3.0-www-modern-3c71bf82";

var LegacyRoot = 0;
var ConcurrentRoot = 1;
Expand Down
4 changes: 2 additions & 2 deletions compiled/facebook-www/ReactART-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -9756,7 +9756,7 @@ var slice = Array.prototype.slice,
return null;
},
bundleType: 0,
version: "18.3.0-www-modern-ce3b7ded",
version: "18.3.0-www-modern-2994e97d",
rendererPackageName: "react-art"
};
var internals$jscomp$inline_1283 = {
Expand Down Expand Up @@ -9787,7 +9787,7 @@ var internals$jscomp$inline_1283 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-ce3b7ded"
reconcilerVersion: "18.3.0-www-modern-2994e97d"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1284 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
8 changes: 7 additions & 1 deletion compiled/facebook-www/ReactDOM-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,11 @@ function useFormStatus() {
throw new Error("Not implemented.");
}
}
function useFormState(action, initialState, url) {
{
throw new Error("Not implemented.");
}
}

var valueStack = [];
var fiberStack;
Expand Down Expand Up @@ -33955,7 +33960,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-classic-ca6e9201";
var ReactVersion = "18.3.0-www-classic-763d3541";

function createPortal$1(
children,
Expand Down Expand Up @@ -47051,6 +47056,7 @@ assign(Internals, {
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
exports.createPortal = createPortal;
exports.createRoot = createRoot;
exports.experimental_useFormState = useFormState;
exports.experimental_useFormStatus = useFormStatus;
exports.findDOMNode = findDOMNode;
exports.flushSync = flushSync;
Expand Down
8 changes: 7 additions & 1 deletion compiled/facebook-www/ReactDOM-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ function useFormStatus() {
throw new Error("Not implemented.");
}
}
function useFormState(action, initialState, url) {
{
throw new Error("Not implemented.");
}
}

var valueStack = [];
var fiberStack;
Expand Down Expand Up @@ -33800,7 +33805,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-www-modern-293df28d";
var ReactVersion = "18.3.0-www-modern-3c71bf82";

function createPortal$1(
children,
Expand Down Expand Up @@ -46120,6 +46125,7 @@ var foundDevTools = injectIntoDevTools({
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
exports.createPortal = createPortal;
exports.createRoot = createRoot;
exports.experimental_useFormState = useFormState;
exports.experimental_useFormStatus = useFormStatus;
exports.flushSync = flushSync;
exports.hydrateRoot = hydrateRoot;
Expand Down
9 changes: 6 additions & 3 deletions compiled/facebook-www/ReactDOM-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -16671,7 +16671,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1783 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-classic-bbf92da7",
version: "18.3.0-www-classic-13155cf9",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2140 = {
Expand Down Expand Up @@ -16701,7 +16701,7 @@ var internals$jscomp$inline_2140 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-classic-bbf92da7"
reconcilerVersion: "18.3.0-www-classic-13155cf9"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2141 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -16767,6 +16767,9 @@ exports.createRoot = function (container, options) {
);
return new ReactDOMRoot(options);
};
exports.experimental_useFormState = function () {
throw Error(formatProdErrorMessage(248));
};
exports.experimental_useFormStatus = function () {
throw Error(formatProdErrorMessage(248));
};
Expand Down Expand Up @@ -16937,4 +16940,4 @@ exports.unstable_renderSubtreeIntoContainer = function (
);
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-classic-bbf92da7";
exports.version = "18.3.0-www-classic-13155cf9";
9 changes: 6 additions & 3 deletions compiled/facebook-www/ReactDOM-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -16201,7 +16201,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1742 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-ce3b7ded",
version: "18.3.0-www-modern-2994e97d",
rendererPackageName: "react-dom"
};
var internals$jscomp$inline_2104 = {
Expand Down Expand Up @@ -16232,7 +16232,7 @@ var internals$jscomp$inline_2104 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-ce3b7ded"
reconcilerVersion: "18.3.0-www-modern-2994e97d"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_2105 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down Expand Up @@ -16291,6 +16291,9 @@ exports.createRoot = function (container, options) {
);
return new ReactDOMRoot(options);
};
exports.experimental_useFormState = function () {
throw Error(formatProdErrorMessage(248));
};
exports.experimental_useFormStatus = function () {
throw Error(formatProdErrorMessage(248));
};
Expand Down Expand Up @@ -16396,4 +16399,4 @@ exports.unstable_createEventHandle = function (type, options) {
return eventHandle;
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-modern-ce3b7ded";
exports.version = "18.3.0-www-modern-2994e97d";
9 changes: 6 additions & 3 deletions compiled/facebook-www/ReactDOM-profiling.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -17446,7 +17446,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1868 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-classic-e408ab62",
version: "18.3.0-www-classic-4c091427",
rendererPackageName: "react-dom"
};
(function (internals) {
Expand Down Expand Up @@ -17490,7 +17490,7 @@ var devToolsConfig$jscomp$inline_1868 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-classic-e408ab62"
reconcilerVersion: "18.3.0-www-classic-4c091427"
});
assign(Internals, {
ReactBrowserEventEmitter: {
Expand Down Expand Up @@ -17543,6 +17543,9 @@ exports.createRoot = function (container, options) {
);
return new ReactDOMRoot(options);
};
exports.experimental_useFormState = function () {
throw Error(formatProdErrorMessage(248));
};
exports.experimental_useFormStatus = function () {
throw Error(formatProdErrorMessage(248));
};
Expand Down Expand Up @@ -17713,7 +17716,7 @@ exports.unstable_renderSubtreeIntoContainer = function (
);
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-classic-e408ab62";
exports.version = "18.3.0-www-classic-4c091427";

/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
Expand Down
9 changes: 6 additions & 3 deletions compiled/facebook-www/ReactDOM-profiling.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -16970,7 +16970,7 @@ Internals.Events = [
var devToolsConfig$jscomp$inline_1827 = {
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: 0,
version: "18.3.0-www-modern-4c5a5509",
version: "18.3.0-www-modern-42b59a98",
rendererPackageName: "react-dom"
};
(function (internals) {
Expand Down Expand Up @@ -17015,7 +17015,7 @@ var devToolsConfig$jscomp$inline_1827 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-www-modern-4c5a5509"
reconcilerVersion: "18.3.0-www-modern-42b59a98"
});
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
exports.createPortal = function (children, container) {
Expand Down Expand Up @@ -17061,6 +17061,9 @@ exports.createRoot = function (container, options) {
);
return new ReactDOMRoot(options);
};
exports.experimental_useFormState = function () {
throw Error(formatProdErrorMessage(248));
};
exports.experimental_useFormStatus = function () {
throw Error(formatProdErrorMessage(248));
};
Expand Down Expand Up @@ -17166,7 +17169,7 @@ exports.unstable_createEventHandle = function (type, options) {
return eventHandle;
};
exports.unstable_runWithPriority = runWithPriority;
exports.version = "18.3.0-www-modern-4c5a5509";
exports.version = "18.3.0-www-modern-42b59a98";

/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
Expand Down
12 changes: 11 additions & 1 deletion compiled/facebook-www/ReactDOMServer-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if (__DEV__) {
var React = require("react");
var ReactDOM = require("react-dom");

var ReactVersion = "18.3.0-www-classic-dcbc1f0e";
var ReactVersion = "18.3.0-www-classic-1747ba9c";

// This refers to a WWW module.
var warningWWW = require("warning");
Expand Down Expand Up @@ -9563,11 +9563,20 @@ function unsupportedSetOptimisticState() {
throw new Error("Cannot update optimistic state while rendering.");
}

function unsupportedDispatchFormState() {
throw new Error("Cannot update form state while rendering.");
}

function useOptimistic(passthrough, reducer) {
resolveCurrentlyRenderingComponent();
return [passthrough, unsupportedSetOptimisticState];
}

function useFormState(action, initialState, url) {
resolveCurrentlyRenderingComponent();
return [initialState, unsupportedDispatchFormState];
}

function useId() {
var task = currentlyRenderingTask;
var treeId = getTreeId(task.treeContext);
Expand Down Expand Up @@ -9671,6 +9680,7 @@ var HooksDispatcher = {

if (enableAsyncActions) {
HooksDispatcher.useOptimistic = useOptimistic;
HooksDispatcher.useFormState = useFormState;
}

var currentResumableState = null;
Expand Down
12 changes: 11 additions & 1 deletion compiled/facebook-www/ReactDOMServer-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if (__DEV__) {
var React = require("react");
var ReactDOM = require("react-dom");

var ReactVersion = "18.3.0-www-modern-55656960";
var ReactVersion = "18.3.0-www-modern-d44f2eb8";

// This refers to a WWW module.
var warningWWW = require("warning");
Expand Down Expand Up @@ -9322,11 +9322,20 @@ function unsupportedSetOptimisticState() {
throw new Error("Cannot update optimistic state while rendering.");
}

function unsupportedDispatchFormState() {
throw new Error("Cannot update form state while rendering.");
}

function useOptimistic(passthrough, reducer) {
resolveCurrentlyRenderingComponent();
return [passthrough, unsupportedSetOptimisticState];
}

function useFormState(action, initialState, url) {
resolveCurrentlyRenderingComponent();
return [initialState, unsupportedDispatchFormState];
}

function useId() {
var task = currentlyRenderingTask;
var treeId = getTreeId(task.treeContext);
Expand Down Expand Up @@ -9430,6 +9439,7 @@ var HooksDispatcher = {

if (enableAsyncActions) {
HooksDispatcher.useOptimistic = useOptimistic;
HooksDispatcher.useFormState = useFormState;
}

var currentResumableState = null;
Expand Down
13 changes: 11 additions & 2 deletions compiled/facebook-www/ReactDOMServer-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -2772,10 +2772,17 @@ function unsupportedStartTransition() {
function unsupportedSetOptimisticState() {
throw Error(formatProdErrorMessage(479));
}
function unsupportedDispatchFormState() {
throw Error(formatProdErrorMessage(485));
}
function useOptimistic(passthrough) {
resolveCurrentlyRenderingComponent();
return [passthrough, unsupportedSetOptimisticState];
}
function useFormState(action, initialState) {
resolveCurrentlyRenderingComponent();
return [initialState, unsupportedDispatchFormState];
}
function unwrapThenable(thenable) {
var index = thenableIndexCounter;
thenableIndexCounter += 1;
Expand Down Expand Up @@ -2870,7 +2877,9 @@ var HooksDispatcher = {
return data;
}
};
enableAsyncActions && (HooksDispatcher.useOptimistic = useOptimistic);
enableAsyncActions &&
((HooksDispatcher.useOptimistic = useOptimistic),
(HooksDispatcher.useFormState = useFormState));
var currentResumableState = null,
DefaultCacheDispatcher = {
getCacheSignal: function () {
Expand Down Expand Up @@ -4390,4 +4399,4 @@ exports.renderToString = function (children, options) {
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
);
};
exports.version = "18.3.0-www-classic-41870992";
exports.version = "18.3.0-www-classic-4f299cee";
13 changes: 11 additions & 2 deletions compiled/facebook-www/ReactDOMServer-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -2764,10 +2764,17 @@ function unsupportedStartTransition() {
function unsupportedSetOptimisticState() {
throw Error(formatProdErrorMessage(479));
}
function unsupportedDispatchFormState() {
throw Error(formatProdErrorMessage(485));
}
function useOptimistic(passthrough) {
resolveCurrentlyRenderingComponent();
return [passthrough, unsupportedSetOptimisticState];
}
function useFormState(action, initialState) {
resolveCurrentlyRenderingComponent();
return [initialState, unsupportedDispatchFormState];
}
function unwrapThenable(thenable) {
var index = thenableIndexCounter;
thenableIndexCounter += 1;
Expand Down Expand Up @@ -2862,7 +2869,9 @@ var HooksDispatcher = {
return data;
}
};
enableAsyncActions && (HooksDispatcher.useOptimistic = useOptimistic);
enableAsyncActions &&
((HooksDispatcher.useOptimistic = useOptimistic),
(HooksDispatcher.useFormState = useFormState));
var currentResumableState = null,
DefaultCacheDispatcher = {
getCacheSignal: function () {
Expand Down Expand Up @@ -4373,4 +4382,4 @@ exports.renderToString = function (children, options) {
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
);
};
exports.version = "18.3.0-www-modern-8d9aaa58";
exports.version = "18.3.0-www-modern-e02b0940";
Loading

0 comments on commit 2bd9065

Please sign in to comment.