@@ -51,6 +51,18 @@ export const getActionShorthandStatusObject = (status: HookActionStatus): HookSh
51
51
} ;
52
52
} ;
53
53
54
+ /**
55
+ * Converts a callback to a ref to avoid triggering re-renders when passed as a
56
+ * prop or avoid re-executing effects when passed as a dependency
57
+ */
58
+ function useCallbackRef < T extends ( arg : any ) => any > ( callback : T | undefined ) : T {
59
+ const callbackRef = React . useRef ( callback ) ;
60
+ React . useEffect ( ( ) => {
61
+ callbackRef . current = callback ;
62
+ } ) ;
63
+ return React . useMemo ( ( ) => ( ( arg ) => callbackRef . current ?.( arg ) as T ) as T , [ ] ) ;
64
+ }
65
+
54
66
export const useActionCallbacks = < ServerError , S extends StandardSchemaV1 | undefined , CVE , Data > ( {
55
67
result,
56
68
input,
@@ -66,20 +78,14 @@ export const useActionCallbacks = <ServerError, S extends StandardSchemaV1 | und
66
78
navigationError : Error | null ;
67
79
thrownError : Error | null ;
68
80
} ) => {
69
- const onExecuteRef = React . useRef ( cb ?. onExecute ) ;
70
- const onSuccessRef = React . useRef ( cb ?. onSuccess ) ;
71
- const onErrorRef = React . useRef ( cb ?. onError ) ;
72
- const onSettledRef = React . useRef ( cb ?. onSettled ) ;
73
- const onNavigationRef = React . useRef ( cb ?. onNavigation ) ;
81
+ const onExecute = useCallbackRef ( cb ?. onExecute ) ;
82
+ const onSuccess = useCallbackRef ( cb ?. onSuccess ) ;
83
+ const onError = useCallbackRef ( cb ?. onError ) ;
84
+ const onSettled = useCallbackRef ( cb ?. onSettled ) ;
85
+ const onNavigation = useCallbackRef ( cb ?. onNavigation ) ;
74
86
75
87
// Execute the callback when the action status changes.
76
- React . useEffect ( ( ) => {
77
- const onExecute = onExecuteRef . current ;
78
- const onSuccess = onSuccessRef . current ;
79
- const onError = onErrorRef . current ;
80
- const onSettled = onSettledRef . current ;
81
- const onNavigation = onNavigationRef . current ;
82
-
88
+ React . useLayoutEffect ( ( ) => {
83
89
const executeCallbacks = async ( ) => {
84
90
switch ( status ) {
85
91
case "executing" :
@@ -99,7 +105,12 @@ export const useActionCallbacks = <ServerError, S extends StandardSchemaV1 | und
99
105
break ;
100
106
case "hasErrored" :
101
107
await Promise . all ( [
102
- Promise . resolve ( onError ?.( { error : { ...result , ...( thrownError ? { thrownError } : { } ) } , input } ) ) ,
108
+ Promise . resolve (
109
+ onError ?.( {
110
+ error : { ...result , ...( thrownError ? { thrownError } : { } ) } ,
111
+ input,
112
+ } )
113
+ ) ,
103
114
Promise . resolve ( onSettled ?.( { result, input } ) ) ,
104
115
] ) ;
105
116
break ;
@@ -128,5 +139,5 @@ export const useActionCallbacks = <ServerError, S extends StandardSchemaV1 | und
128
139
} ;
129
140
130
141
executeCallbacks ( ) . catch ( console . error ) ;
131
- } , [ input , status , result , navigationError , thrownError ] ) ;
142
+ } , [ input , status , result , navigationError , thrownError , onExecute , onSuccess , onSettled , onError , onNavigation ] ) ;
132
143
} ;
0 commit comments