Skip to content

Commit 655915c

Browse files
committed
Implement experimental_useOptimisticState (#26740)
This adds an experimental hook tentatively called useOptimisticState. (The actual name needs some bikeshedding.) The headline feature is that you can use it to implement optimistic updates. If you set some optimistic state during a transition/action, the state will be automatically reverted once the transition completes. Another feature is that the optimistic updates will be continually rebased on top of the latest state. It's easiest to explain with examples; we'll publish documentation as the API gets closer to stabilizing. See tests for now. Technically the use cases for this hook are broader than just optimistic updates; you could use it implement any sort of "pending" state, such as the ones exposed by useTransition and useFormStatus. But we expect people will most often reach for this hook to implement the optimistic update pattern; simpler cases are covered by those other hooks. DiffTrain build for [491aec5](491aec5)
1 parent 0f3ca2b commit 655915c

30 files changed

+5027
-2485
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9545e4810c2dc8922f575b6d8f726503a7345d0c
1+
491aec5d6113ce5bae7c10966bc38a4a8fc091a8

compiled/facebook-www/React-dev.classic.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ if (
2727
}
2828
"use strict";
2929

30-
var ReactVersion = "18.3.0-www-classic-0ae2769a";
30+
var ReactVersion = "18.3.0-www-classic-9b9fa2f6";
3131

3232
// ATTENTION
3333
// When adding new symbols to this file,
@@ -2026,6 +2026,11 @@ function useEffectEvent(callback) {
20262026

20272027
return dispatcher.useEffectEvent(callback);
20282028
}
2029+
function useOptimisticState(passthrough, reducer) {
2030+
var dispatcher = resolveDispatcher(); // $FlowFixMe[not-a-function] This is unstable, thus optional
2031+
2032+
return dispatcher.useOptimisticState(passthrough, reducer);
2033+
}
20292034

20302035
// Helpers to patch console.logs to avoid logging during side-effect free
20312036
// replaying on render function. This currently only patches the object
@@ -4175,6 +4180,7 @@ exports.createMutableSource = createMutableSource;
41754180
exports.createRef = createRef;
41764181
exports.createServerContext = createServerContext;
41774182
exports.experimental_useEffectEvent = useEffectEvent;
4183+
exports.experimental_useOptimisticState = useOptimisticState;
41784184
exports.forwardRef = forwardRef;
41794185
exports.isValidElement = isValidElement$1;
41804186
exports.jsx = jsx;

compiled/facebook-www/React-dev.modern.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ if (
2727
}
2828
"use strict";
2929

30-
var ReactVersion = "18.3.0-www-modern-3898c4ac";
30+
var ReactVersion = "18.3.0-www-modern-32c95640";
3131

3232
// ATTENTION
3333
// When adding new symbols to this file,
@@ -2026,6 +2026,11 @@ function useEffectEvent(callback) {
20262026

20272027
return dispatcher.useEffectEvent(callback);
20282028
}
2029+
function useOptimisticState(passthrough, reducer) {
2030+
var dispatcher = resolveDispatcher(); // $FlowFixMe[not-a-function] This is unstable, thus optional
2031+
2032+
return dispatcher.useOptimisticState(passthrough, reducer);
2033+
}
20292034

20302035
// Helpers to patch console.logs to avoid logging during side-effect free
20312036
// replaying on render function. This currently only patches the object
@@ -4139,6 +4144,7 @@ exports.createMutableSource = createMutableSource;
41394144
exports.createRef = createRef;
41404145
exports.createServerContext = createServerContext;
41414146
exports.experimental_useEffectEvent = useEffectEvent;
4147+
exports.experimental_useOptimisticState = useOptimisticState;
41424148
exports.forwardRef = forwardRef;
41434149
exports.isValidElement = isValidElement$1;
41444150
exports.jsx = jsx;

compiled/facebook-www/React-prod.classic.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,12 @@ exports.createServerContext = function (globalName, defaultValue) {
536536
exports.experimental_useEffectEvent = function (callback) {
537537
return ReactCurrentDispatcher.current.useEffectEvent(callback);
538538
};
539+
exports.experimental_useOptimisticState = function (passthrough, reducer) {
540+
return ReactCurrentDispatcher.current.useOptimisticState(
541+
passthrough,
542+
reducer
543+
);
544+
};
539545
exports.forwardRef = function (render) {
540546
return { $$typeof: REACT_FORWARD_REF_TYPE, render: render };
541547
};
@@ -646,4 +652,4 @@ exports.useSyncExternalStore = function (
646652
);
647653
};
648654
exports.useTransition = useTransition;
649-
exports.version = "18.3.0-www-classic-993671e7";
655+
exports.version = "18.3.0-www-classic-f9e05cb4";

compiled/facebook-www/React-prod.modern.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,12 @@ exports.createServerContext = function (globalName, defaultValue) {
529529
exports.experimental_useEffectEvent = function (callback) {
530530
return ReactCurrentDispatcher.current.useEffectEvent(callback);
531531
};
532+
exports.experimental_useOptimisticState = function (passthrough, reducer) {
533+
return ReactCurrentDispatcher.current.useOptimisticState(
534+
passthrough,
535+
reducer
536+
);
537+
};
532538
exports.forwardRef = function (render) {
533539
return { $$typeof: REACT_FORWARD_REF_TYPE, render: render };
534540
};
@@ -638,4 +644,4 @@ exports.useSyncExternalStore = function (
638644
);
639645
};
640646
exports.useTransition = useTransition;
641-
exports.version = "18.3.0-www-modern-d633a116";
647+
exports.version = "18.3.0-www-modern-2e6e6832";

compiled/facebook-www/React-profiling.classic.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,12 @@ exports.createServerContext = function (globalName, defaultValue) {
547547
exports.experimental_useEffectEvent = function (callback) {
548548
return ReactCurrentDispatcher.current.useEffectEvent(callback);
549549
};
550+
exports.experimental_useOptimisticState = function (passthrough, reducer) {
551+
return ReactCurrentDispatcher.current.useOptimisticState(
552+
passthrough,
553+
reducer
554+
);
555+
};
550556
exports.forwardRef = function (render) {
551557
return { $$typeof: REACT_FORWARD_REF_TYPE, render: render };
552558
};
@@ -657,7 +663,7 @@ exports.useSyncExternalStore = function (
657663
);
658664
};
659665
exports.useTransition = useTransition;
660-
exports.version = "18.3.0-www-classic-1306d154";
666+
exports.version = "18.3.0-www-classic-8122ba25";
661667

662668
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
663669
if (

compiled/facebook-www/React-profiling.modern.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,12 @@ exports.createServerContext = function (globalName, defaultValue) {
540540
exports.experimental_useEffectEvent = function (callback) {
541541
return ReactCurrentDispatcher.current.useEffectEvent(callback);
542542
};
543+
exports.experimental_useOptimisticState = function (passthrough, reducer) {
544+
return ReactCurrentDispatcher.current.useOptimisticState(
545+
passthrough,
546+
reducer
547+
);
548+
};
543549
exports.forwardRef = function (render) {
544550
return { $$typeof: REACT_FORWARD_REF_TYPE, render: render };
545551
};
@@ -649,7 +655,7 @@ exports.useSyncExternalStore = function (
649655
);
650656
};
651657
exports.useTransition = useTransition;
652-
exports.version = "18.3.0-www-modern-01657d31";
658+
exports.version = "18.3.0-www-modern-eff148b0";
653659

654660
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
655661
if (

0 commit comments

Comments
 (0)