@@ -16,16 +16,6 @@ import type {
16
16
} from "./hooks.types" ;
17
17
import { isError } from "./utils" ;
18
18
19
- /**
20
- * Default value for `result` object returned by `useAction`, `useOptimisticAction` and `useStateAction` hooks.
21
- */
22
- export const EMPTY_HOOK_RESULT = {
23
- data : undefined ,
24
- fetchError : undefined ,
25
- serverError : undefined ,
26
- validationErrors : undefined ,
27
- } satisfies HookResult < any , any , any , any , any , any > ;
28
-
29
19
const getActionStatus = <
30
20
ServerError ,
31
21
S extends Schema | undefined ,
@@ -138,7 +128,7 @@ export const useAction = <
138
128
utils ?: HookCallbacks < ServerError , S , BAS , CVE , CBAVE , Data >
139
129
) => {
140
130
const [ , startTransition ] = React . useTransition ( ) ;
141
- const [ result , setResult ] = React . useState < HookResult < ServerError , S , BAS , CVE , CBAVE , Data > > ( EMPTY_HOOK_RESULT ) ;
131
+ const [ result , setResult ] = React . useState < HookResult < ServerError , S , BAS , CVE , CBAVE , Data > > ( { } ) ;
142
132
const [ clientInput , setClientInput ] = React . useState < S extends Schema ? InferIn < S > : void > ( ) ;
143
133
const [ isExecuting , setIsExecuting ] = React . useState ( false ) ;
144
134
const [ isIdle , setIsIdle ] = React . useState ( true ) ;
@@ -147,13 +137,9 @@ export const useAction = <
147
137
148
138
const execute = React . useCallback (
149
139
( input : S extends Schema ? InferIn < S > : void ) => {
150
- setIsIdle ( false ) ;
151
- setClientInput ( input ) ;
152
- setIsExecuting ( true ) ;
153
-
154
- return startTransition ( ( ) => {
155
- return safeActionFn ( input as S extends Schema ? InferIn < S > : undefined )
156
- . then ( ( res ) => setResult ( res ?? EMPTY_HOOK_RESULT ) )
140
+ startTransition ( ( ) => {
141
+ safeActionFn ( input as S extends Schema ? InferIn < S > : undefined )
142
+ . then ( ( res ) => setResult ( res ?? { } ) )
157
143
. catch ( ( e ) => {
158
144
if ( isRedirectError ( e ) || isNotFoundError ( e ) ) {
159
145
throw e ;
@@ -165,25 +151,27 @@ export const useAction = <
165
151
setIsExecuting ( false ) ;
166
152
} ) ;
167
153
} ) ;
154
+
155
+ ReactDOM . flushSync ( ( ) => {
156
+ setIsIdle ( false ) ;
157
+ setClientInput ( input ) ;
158
+ setIsExecuting ( true ) ;
159
+ } ) ;
168
160
} ,
169
161
[ safeActionFn ]
170
162
) ;
171
163
172
164
const executeAsync = React . useCallback (
173
165
( input : S extends Schema ? InferIn < S > : void ) => {
174
- setIsIdle ( false ) ;
175
- setClientInput ( input ) ;
176
- setIsExecuting ( true ) ;
177
-
178
- return new Promise < Awaited < ReturnType < typeof safeActionFn > > > ( ( resolve , reject ) => {
166
+ const fn = new Promise < Awaited < ReturnType < typeof safeActionFn > > > ( ( resolve , reject ) => {
179
167
startTransition ( ( ) => {
180
168
safeActionFn ( input as S extends Schema ? InferIn < S > : undefined )
181
169
. then ( ( res ) => {
170
+ setResult ( res ?? { } ) ;
182
171
resolve ( res ) ;
183
172
} )
184
173
. catch ( ( e ) => {
185
174
if ( isRedirectError ( e ) || isNotFoundError ( e ) ) {
186
- setResult ( EMPTY_HOOK_RESULT ) ;
187
175
throw e ;
188
176
}
189
177
@@ -195,18 +183,26 @@ export const useAction = <
195
183
} ) ;
196
184
} ) ;
197
185
} ) ;
186
+
187
+ ReactDOM . flushSync ( ( ) => {
188
+ setIsIdle ( false ) ;
189
+ setClientInput ( input ) ;
190
+ setIsExecuting ( true ) ;
191
+ } ) ;
192
+
193
+ return fn ;
198
194
} ,
199
195
[ safeActionFn ]
200
196
) ;
201
197
202
198
const reset = ( ) => {
203
199
setIsIdle ( true ) ;
204
200
setClientInput ( undefined ) ;
205
- setResult ( EMPTY_HOOK_RESULT ) ;
201
+ setResult ( { } ) ;
206
202
} ;
207
203
208
204
useActionCallbacks ( {
209
- result : result ?? EMPTY_HOOK_RESULT ,
205
+ result : result ?? { } ,
210
206
input : clientInput as S extends Schema ? InferIn < S > : undefined ,
211
207
status,
212
208
cb : utils ,
@@ -246,7 +242,7 @@ export const useOptimisticAction = <
246
242
} & HookCallbacks < ServerError , S , BAS , CVE , CBAVE , Data >
247
243
) => {
248
244
const [ , startTransition ] = React . useTransition ( ) ;
249
- const [ result , setResult ] = React . useState < HookResult < ServerError , S , BAS , CVE , CBAVE , Data > > ( EMPTY_HOOK_RESULT ) ;
245
+ const [ result , setResult ] = React . useState < HookResult < ServerError , S , BAS , CVE , CBAVE , Data > > ( { } ) ;
250
246
const [ clientInput , setClientInput ] = React . useState < S extends Schema ? InferIn < S > : void > ( ) ;
251
247
const [ isExecuting , setIsExecuting ] = React . useState ( false ) ;
252
248
const [ isIdle , setIsIdle ] = React . useState ( true ) ;
@@ -259,14 +255,10 @@ export const useOptimisticAction = <
259
255
260
256
const execute = React . useCallback (
261
257
( input : S extends Schema ? InferIn < S > : void ) => {
262
- setIsIdle ( false ) ;
263
- setClientInput ( input ) ;
264
- setIsExecuting ( true ) ;
265
-
266
- return startTransition ( ( ) => {
258
+ startTransition ( ( ) => {
267
259
setOptimisticValue ( input as S extends Schema ? InferIn < S > : undefined ) ;
268
- return safeActionFn ( input as S extends Schema ? InferIn < S > : undefined )
269
- . then ( ( res ) => setResult ( res ?? EMPTY_HOOK_RESULT ) )
260
+ safeActionFn ( input as S extends Schema ? InferIn < S > : undefined )
261
+ . then ( ( res ) => setResult ( res ?? { } ) )
270
262
. catch ( ( e ) => {
271
263
if ( isRedirectError ( e ) || isNotFoundError ( e ) ) {
272
264
throw e ;
@@ -278,26 +270,28 @@ export const useOptimisticAction = <
278
270
setIsExecuting ( false ) ;
279
271
} ) ;
280
272
} ) ;
273
+
274
+ ReactDOM . flushSync ( ( ) => {
275
+ setIsIdle ( false ) ;
276
+ setClientInput ( input ) ;
277
+ setIsExecuting ( true ) ;
278
+ } ) ;
281
279
} ,
282
280
[ safeActionFn , setOptimisticValue ]
283
281
) ;
284
282
285
283
const executeAsync = React . useCallback (
286
284
( input : S extends Schema ? InferIn < S > : void ) => {
287
- setIsIdle ( false ) ;
288
- setClientInput ( input ) ;
289
- setIsExecuting ( true ) ;
290
-
291
- return new Promise < Awaited < ReturnType < typeof safeActionFn > > > ( ( resolve , reject ) => {
285
+ const fn = new Promise < Awaited < ReturnType < typeof safeActionFn > > > ( ( resolve , reject ) => {
292
286
startTransition ( ( ) => {
293
287
setOptimisticValue ( input as S extends Schema ? InferIn < S > : undefined ) ;
294
288
safeActionFn ( input as S extends Schema ? InferIn < S > : undefined )
295
289
. then ( ( res ) => {
290
+ setResult ( res ?? { } ) ;
296
291
resolve ( res ) ;
297
292
} )
298
293
. catch ( ( e ) => {
299
294
if ( isRedirectError ( e ) || isNotFoundError ( e ) ) {
300
- setResult ( EMPTY_HOOK_RESULT ) ;
301
295
throw e ;
302
296
}
303
297
@@ -309,18 +303,26 @@ export const useOptimisticAction = <
309
303
} ) ;
310
304
} ) ;
311
305
} ) ;
306
+
307
+ ReactDOM . flushSync ( ( ) => {
308
+ setIsIdle ( false ) ;
309
+ setClientInput ( input ) ;
310
+ setIsExecuting ( true ) ;
311
+ } ) ;
312
+
313
+ return fn ;
312
314
} ,
313
315
[ safeActionFn , setOptimisticValue ]
314
316
) ;
315
317
316
318
const reset = ( ) => {
317
319
setIsIdle ( true ) ;
318
320
setClientInput ( undefined ) ;
319
- setResult ( EMPTY_HOOK_RESULT ) ;
321
+ setResult ( { } ) ;
320
322
} ;
321
323
322
324
useActionCallbacks ( {
323
- result : result ?? EMPTY_HOOK_RESULT ,
325
+ result : result ?? { } ,
324
326
input : clientInput as S extends Schema ? InferIn < S > : undefined ,
325
327
status,
326
328
cb : {
@@ -366,22 +368,21 @@ export const useStateAction = <
366
368
) => {
367
369
const [ result , dispatcher , isExecuting ] = React . useActionState (
368
370
safeActionFn ,
369
- utils ?. initResult ?? EMPTY_HOOK_RESULT ,
371
+ utils ?. initResult ?? { } ,
370
372
utils ?. permalink
371
373
) ;
372
374
const [ isIdle , setIsIdle ] = React . useState ( true ) ;
373
375
const [ clientInput , setClientInput ] = React . useState < S extends Schema ? InferIn < S > : void > ( ) ;
374
376
const status = getActionStatus < ServerError , S , BAS , CVE , CBAVE , Data > ( {
375
377
isExecuting,
376
- result : result ?? EMPTY_HOOK_RESULT ,
378
+ result : result ?? { } ,
377
379
isIdle,
378
380
} ) ;
379
381
380
382
const execute = React . useCallback (
381
383
( input : S extends Schema ? InferIn < S > : void ) => {
382
384
dispatcher ( input as S extends Schema ? InferIn < S > : undefined ) ;
383
385
384
- // eslint-disable-next-line
385
386
ReactDOM . flushSync ( ( ) => {
386
387
setIsIdle ( false ) ;
387
388
setClientInput ( input ) ;
@@ -391,7 +392,7 @@ export const useStateAction = <
391
392
) ;
392
393
393
394
useActionCallbacks ( {
394
- result : result ?? EMPTY_HOOK_RESULT ,
395
+ result : result ?? { } ,
395
396
input : clientInput as S extends Schema ? InferIn < S > : undefined ,
396
397
status,
397
398
cb : {
0 commit comments