@@ -62,8 +62,6 @@ function PydanticFormContextProvider({
62
62
labelProvider,
63
63
customDataProvider,
64
64
customDataProviderCacheKey,
65
- formStructureMutator,
66
- fieldDetailProvider,
67
65
resetButtonAlternative,
68
66
allowUntouchedSubmit,
69
67
skipSuccessNotice,
@@ -72,27 +70,22 @@ function PydanticFormContextProvider({
72
70
cancelButton,
73
71
} = config ;
74
72
75
- const awaitReset = async ( payLoad : FieldValues = { } ) => {
76
- rhf . reset ( payLoad ) ;
77
- await new Promise ( ( resolve ) => setTimeout ( resolve , 0 ) ) ; // wait one tick
78
- } ;
79
-
80
73
const [ formInputHistory , setFormInputHistory ] = useState (
81
74
new Map < string , object > ( ) ,
82
75
) ;
83
76
const [ formInputData , setFormInputData ] = useState < object [ ] > ( [ ] ) ;
84
77
85
78
const formRef = useRef < string > ( formKey ) ;
86
79
87
- const updateHistory = async (
88
- formInput : object ,
89
- previousSteps : object [ ] ,
90
- ) => {
91
- const hashOfPreviousSteps = await getHashForArray ( previousSteps ) ;
92
- setFormInputHistory ( ( prevState ) =>
93
- prevState . set ( hashOfPreviousSteps , formInput ) ,
94
- ) ;
95
- } ;
80
+ const updateHistory = useCallback (
81
+ async ( formInput : object , previousSteps : object [ ] ) => {
82
+ const hashOfPreviousSteps = await getHashForArray ( previousSteps ) ;
83
+ setFormInputHistory ( ( prevState ) =>
84
+ prevState . set ( hashOfPreviousSteps , formInput ) ,
85
+ ) ;
86
+ } ,
87
+ [ ] ,
88
+ ) ;
96
89
97
90
const goToPreviousStep = ( formInput : object ) => {
98
91
setFormInputData ( ( prevState ) => {
@@ -122,17 +115,21 @@ function PydanticFormContextProvider({
122
115
error,
123
116
} = useApiProvider ( formKey , formInputData , apiProvider , metaData ) ;
124
117
125
- const emptyRawSchema : PydanticFormSchemaRawJson = {
126
- type : PydanticFormFieldType . OBJECT ,
127
- properties : { } ,
128
- } ;
118
+ const emptyRawSchema : PydanticFormSchemaRawJson = useMemo (
119
+ ( ) => ( {
120
+ type : PydanticFormFieldType . OBJECT ,
121
+ properties : { } ,
122
+ } ) ,
123
+ [ ] ,
124
+ ) ;
125
+
129
126
const [ rawSchema , setRawSchema ] =
130
127
useState < PydanticFormSchemaRawJson > ( emptyRawSchema ) ;
131
128
const [ hasNext , setHasNext ] = useState < boolean > ( false ) ;
132
129
133
130
// extract the JSON schema to a more usable custom schema
134
131
const { pydanticFormSchema, isLoading : isParsingSchema } =
135
- usePydanticFormParser ( rawSchema , formKey , formLabels ?. labels ) ;
132
+ usePydanticFormParser ( rawSchema , formLabels ?. labels ) ;
136
133
137
134
// build validation rules based on custom schema
138
135
const zodSchema = useGetZodValidator (
@@ -164,6 +161,14 @@ function PydanticFormContextProvider({
164
161
values : initialData ,
165
162
} ) ;
166
163
164
+ const awaitReset = useCallback (
165
+ async ( payLoad : FieldValues = { } ) => {
166
+ rhf . reset ( payLoad ) ;
167
+ await new Promise ( ( resolve ) => setTimeout ( resolve , 0 ) ) ; // wait one tick
168
+ } ,
169
+ [ rhf ] ,
170
+ ) ;
171
+
167
172
const addFormInputData = useCallback (
168
173
( formInput : object , replaceInsteadOfAdd = false ) => {
169
174
setFormInputData ( ( currentInputs ) => {
@@ -208,7 +213,7 @@ function PydanticFormContextProvider({
208
213
awaitReset ( ) ;
209
214
rhf . trigger ( ) ;
210
215
} ,
211
- [ rhf ] ,
216
+ [ awaitReset , rhf ] ,
212
217
) ;
213
218
214
219
const resetErrorDetails = useCallback ( ( ) => {
@@ -226,7 +231,7 @@ function PydanticFormContextProvider({
226
231
setIsFullFilled ( false ) ;
227
232
setRawSchema ( emptyRawSchema ) ;
228
233
setHasNext ( false ) ;
229
- } , [ ] ) ;
234
+ } , [ emptyRawSchema ] ) ;
230
235
231
236
const PydanticFormContextState = {
232
237
// to prevent an issue where the sending state hangs
@@ -299,7 +304,6 @@ function PydanticFormContextProvider({
299
304
// When a formKey changes we reset the form input data
300
305
useEffect ( ( ) => {
301
306
if ( formKey !== formRef . current ) {
302
- console . log ( 'formchange' , formKey , formRef . current ) ;
303
307
// When the formKey changes we need to reset the form input data
304
308
setFormInputData ( [ ] ) ;
305
309
setFormInputHistory ( new Map < string , object > ( ) ) ;
@@ -327,7 +331,45 @@ function PydanticFormContextProvider({
327
331
328
332
setFormInputHistory ( new Map < string , object > ( ) ) ;
329
333
// eslint-disable-next-line react-hooks/exhaustive-deps
330
- } , [ apiResponse , isFullFilled ] ) ;
334
+ } , [ apiResponse , isFullFilled ] ) ; // Avoid completing the dependencies array here to avoid unwanted resetFormData calls
335
+
336
+ // this handles errors throws by the useApiProvider call
337
+ // for instance unexpected 500 errors
338
+ useEffect ( ( ) => {
339
+ if ( ! error ) {
340
+ return ;
341
+ }
342
+
343
+ setErrorDetails ( {
344
+ detail : 'Something unexpected went wrong' ,
345
+ source : [ ] ,
346
+ mapped : { } ,
347
+ } ) ;
348
+ } , [ error ] ) ;
349
+
350
+ useEffect ( ( ) => {
351
+ const getLocale = ( ) => {
352
+ switch ( locale ) {
353
+ case Locale . enGB :
354
+ return z . locales . en ( ) ;
355
+ case Locale . nlNL :
356
+ return z . locales . nl ( ) ;
357
+ default :
358
+ return z . locales . en ( ) ;
359
+ }
360
+ } ;
361
+
362
+ z . config ( getLocale ( ) ) ;
363
+ } , [ locale ] ) ;
364
+
365
+ useEffect ( ( ) => {
366
+ getHashForArray ( formInputData ) . then ( ( hash ) => {
367
+ const currentStepFromHistory = formInputHistory . get ( hash ) ;
368
+ if ( currentStepFromHistory ) {
369
+ awaitReset ( currentStepFromHistory ) ;
370
+ }
371
+ } ) ;
372
+ } , [ awaitReset , formInputData , formInputHistory , rhf ] ) ;
331
373
332
374
return (
333
375
< PydanticFormContext . Provider value = { PydanticFormContextState } >
0 commit comments