You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My codebase is quite small and I have only 3 form as of today, but I have one which is quite complex. It include field array with complex object. Multiple async fetching of data during the form life cycle. Using external store (Zustand) to maintain the state of the form. For this last part I'm not 100% sure if this is the best way, but I didn't figure yet a way to handle this differently.
Using Zustand together with the form (good or bad?)
Basically I have a timesheet form with a main date and project and for this date and project I can enter multiple entries which consist of a Code - Service - Details - Quantity - Unit Price - Billable.
The Code list depend on the selected project and the Unit Price depend on the selected Code (async fetch).
And the form only needs to store the projectId, codeId. But the project itself is a more complex object, same for the code and even the price is also an object. So in order to store those values (for example if I need to display the name and client for the project, also for the edit feature, I will need to give the full context for to the form) I choose to use Zustand. This force me to do some weird synchronization between the store and the form and I wonder if anybody could advise me a better way to handle such complex form.
My main idea was that I want my form state to keep only the data that I want to send to the POST request. But I'm starting to wonder if that is really needed and if I should not store all the data (even the one not related to the POST endpoint) into the form state and only process it during the submit.
Anyway I digress.
Reflexions
My main purpose of this post was to give some hints on the challenge I had and maybe some questions.
The whole process is quite straightforward, but we need to read and re-read the doc and example to fully know what we are doing. Also there are some stuff required to be done on RHF and we are not sure if we need to do those as well or not:
onError during submit
clearErrors() after a reset. -> It seems that this is automatic with TS Form
Do we need to use something similar to field.trigger("fieldName") after doing form.setFieldValue("fieldName") in order to trigger validation?
Using RHF, the doc advise to do this in order to reset a form :
I wonder if I should do the equivalent with TS Form or if with TS form reseting the form directly in a onSuccess callback (of my mutation for ex.) is enough.
Although there is a doc for that one, I wonder if we should always use the withForm when we need to decompose our form and different field into different components. Or is there another way of breaking components?
From my implementation, it seems that using withForm is actually very nice as we always have the full form context passed down and we are free to do whatever we want. I feel like the small over-head of wrapping my components inside a withForm is not that of a big deal.
I also want to add that I use to wrap some components with withForm not in the purpose of reusing the component but in order to break my big form into smaller pieces.
Handler
Another point that I didn't yet totally figure it out, is most of the example show code in the different callback directly in the JSX. Some of the good practice is to write the handler in a function and pass it to the JSX props. For example I have a function that is called handleAddEntry which add a field in the field array as well as add an entry in the Zustand store. The Array example show that we have to use field.pushValue within a form.Field component. How can I declare my function outside of the component? Is there a way to have access to the field outside of or should I pass the field as a param to the function (and what would be the type)?
Ok, as I write this I'm also trying out so for now I have done 2 way and I think the second one should be the best. 1.
I don't know why but the <form.Subscribe /> in point 2 create an Maximum update depth exceeded error message from react. Ok, I found out. It was because I have both code 1. and 2. in my component. So it seems that having both const entries = useStore(form.store, (state) => state.values.entries); and <form.Subscribe selector={(state) => state.values.entries} /> can create an infinite loop. This was the case when I was doing a form.reset(). Good to know.
Ok both 1 and 2 are wrong and I discover the form.pushFieldValue which seems to be what I was looking for. No need to worry to pass down field props or complicated stuff.
Checkbox is set to isTouched automatically
I have not yet been able to reproduce in a small example in stackblitz but I have a case where I my checkbox is automatically set to isTouched even though I don't touch it. It is in the context of a array field and I'm not sure what cause this behavior. I will need to investigate more but for now I can live with it.
Conclusions
Sorry if this feel a little bit a mess in the organization of this message but I just put my observations as they come. I hope this can be helpful for anybody who could struggle with the same issues/questions.
For now, even though I struggle a bit with the new API, I already start to love what I learn and start to feel more and more comfortable with it.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Moving from RHF
I'm migrating from RHF to TS Form.
Description of the project
My codebase is quite small and I have only 3 form as of today, but I have one which is quite complex. It include field array with complex object. Multiple async fetching of data during the form life cycle. Using external store (Zustand) to maintain the state of the form. For this last part I'm not 100% sure if this is the best way, but I didn't figure yet a way to handle this differently.
Using Zustand together with the form (good or bad?)
Basically I have a timesheet form with a main date and project and for this date and project I can enter multiple entries which consist of a Code - Service - Details - Quantity - Unit Price - Billable.
The Code list depend on the selected project and the Unit Price depend on the selected Code (async fetch).
And the form only needs to store the
projectId
,codeId
. But the project itself is a more complex object, same for the code and even the price is also an object. So in order to store those values (for example if I need to display the name and client for the project, also for the edit feature, I will need to give the full context for to the form) I choose to use Zustand. This force me to do some weird synchronization between the store and the form and I wonder if anybody could advise me a better way to handle such complex form.My main idea was that I want my form state to keep only the data that I want to send to the POST request. But I'm starting to wonder if that is really needed and if I should not store all the data (even the one not related to the POST endpoint) into the form state and only process it during the submit.
Anyway I digress.
Reflexions
My main purpose of this post was to give some hints on the challenge I had and maybe some questions.
The whole process is quite straightforward, but we need to read and re-read the doc and example to fully know what we are doing. Also there are some stuff required to be done on RHF and we are not sure if we need to do those as well or not:
onError
during submitclearErrors()
after a reset. -> It seems that this is automatic with TS Formfield.trigger("fieldName")
after doingform.setFieldValue("fieldName")
in order to trigger validation?I wonder if I should do the equivalent with TS Form or if with TS form reseting the form directly in a
onSuccess
callback (of my mutation for ex.) is enough.Equivalent in TS Form:
Breaking big forms into smaller pieces
Although there is a doc for that one, I wonder if we should always use the
withForm
when we need to decompose our form and different field into different components. Or is there another way of breaking components?From my implementation, it seems that using
withForm
is actually very nice as we always have the full form context passed down and we are free to do whatever we want. I feel like the small over-head of wrapping my components inside awithForm
is not that of a big deal.I also want to add that I use to wrap some components with
withForm
not in the purpose of reusing the component but in order to break my big form into smaller pieces.Handler
Another point that I didn't yet totally figure it out, is most of the example show code in the different callback directly in the JSX. Some of the good practice is to write the handler in a function and pass it to the JSX props. For example I have a function that is called
handleAddEntry
which add a field in the field array as well as add an entry in the Zustand store. The Array example show that we have to usefield.pushValue
within a form.Field component. How can I declare my function outside of the component? Is there a way to have access to the field outside of or should I pass the field as a param to the function (and what would be the type)?Ok, as I write this I'm also trying out so for now I have done 2 way and I think the second one should be the best.
1.
2.
I don't know why but the
<form.Subscribe />
in point 2 create anMaximum update depth exceeded
error message from react. Ok, I found out. It was because I have both code 1. and 2. in my component. So it seems that having bothconst entries = useStore(form.store, (state) => state.values.entries);
and<form.Subscribe selector={(state) => state.values.entries} />
can create an infinite loop. This was the case when I was doing aform.reset()
. Good to know.Ok both 1 and 2 are wrong and I discover the
form.pushFieldValue
which seems to be what I was looking for. No need to worry to pass down field props or complicated stuff.Checkbox is set to isTouched automatically
I have not yet been able to reproduce in a small example in stackblitz but I have a case where I my checkbox is automatically set to isTouched even though I don't touch it. It is in the context of a array field and I'm not sure what cause this behavior. I will need to investigate more but for now I can live with it.
Conclusions
Sorry if this feel a little bit a mess in the organization of this message but I just put my observations as they come. I hope this can be helpful for anybody who could struggle with the same issues/questions.
For now, even though I struggle a bit with the new API, I already start to love what I learn and start to feel more and more comfortable with it.
Welcome to the future!
Beta Was this translation helpful? Give feedback.
All reactions