fair-rose
fair-rose5mo ago

watching varying fields (by registered name) causes app to slow down

i have a very complicated advanced edit form. i want to not show some fields depending on other's value. for that im using the watch api from react-hook-form. the problem is that since my form is nested im registering some fields by their index in the array. if there will be 5 of them my utility function registers them like this a.b.0.visa_req a.b.1.visa_req a.b.2.visa_req a.b.3.visa_req a.b.4.visa_req there fore, im watching them like this in this code. //this watches only the 0th index. i want to watch them all const watchingValidity = watch("a.b.0.min_validity_req"); let updatedHiddenFields = [...hiddenFields]; React.useEffect(() => { if (watching.a && watching.a.b) { watching.a.b.forEach((item, index) => { const field = a.b.${index}.visa_info_group; // the field that i want to close if (item.visa_req === "not_required" && !updatedHiddenFields.includes(field)) { updatedHiddenFields.push(field); setHiddenFields(updatedHiddenFields); } else if (item.visa_req === "required") { updatedHiddenFields = updatedHiddenFields.filter(f => f !== field); setHiddenFields(updatedHiddenFields); } }); } }, [watching]); React.useEffect(() => { const fieldKeys = [ a.b.0.min_validity_days, a.b.0.min_validity_ref ]; setHiddenFields(watchingValidity ? updatedHiddenFields.filter(f => !fieldKeys.includes(f)) : [...updatedHiddenFields, ...fieldKeys]); }, [watchingValidity]); when one value changes i dont want to update the whole form. i want to update just one field. thats why its working so slowly. any solution ideas?? watchin a.b has also the same effect as watching a.b.${index}.visa_req
3 Replies
kapa.ai
kapa.ai5mo ago
Hi @atakan0298. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The performance issue you're experiencing might be due to the fact that the watch function from react-hook-form triggers re-renders every time the watched field changes. This can lead to performance issues in complex forms with many fields, especially if you're watching multiple fields. One way to optimize this is to minimize the number of fields you're watching. Instead of watching each field individually, you could watch the entire a.b array and then use the returned value to conditionally render your fields. This way, you're only causing one re-render instead of multiple. Here's an example of how you could do this:
const watching = watch("a.b");

React.useEffect(() => {
if (watching) {
watching.forEach((item, index) => {
const field = `a.b.${index}.visa_info_group`; // the field that i want to close

if (item.visa_req === "not_required" && !updatedHiddenFields.includes(field)) {
updatedHiddenFields.push(field);
setHiddenFields(updatedHiddenFields);
} else if (item.visa_req === "required") {
updatedHiddenFields = updatedHiddenFields.filter(f => f !== field);
setHiddenFields(updatedHiddenFields);
}
});
}
}, [watching]);
const watching = watch("a.b");

React.useEffect(() => {
if (watching) {
watching.forEach((item, index) => {
const field = `a.b.${index}.visa_info_group`; // the field that i want to close

if (item.visa_req === "not_required" && !updatedHiddenFields.includes(field)) {
updatedHiddenFields.push(field);
setHiddenFields(updatedHiddenFields);
} else if (item.visa_req === "required") {
updatedHiddenFields = updatedHiddenFields.filter(f => f !== field);
setHiddenFields(updatedHiddenFields);
}
});
}
}, [watching]);
In this example, you're watching the entire a.b array. When the watch function returns a new value, you're iterating over the array and updating your hiddenFields state accordingly. This should result in fewer re-renders and improve the performance of your form. However, keep in mind that this approach might not be suitable for all use cases. If you need to watch individual fields for some reason, you might need to look into other ways to optimize your form, such as using memoization or splitting your form into smaller components. For more information on how to use the watch function, you can refer to this blog post (https://refine.dev/blog/react-hook-form-validation-examples#how-to-conditionally-render-input-fields​) on the Refine website. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@594767835386085376> kapa.ai is still learning and improving, please let us know how it did by reacting below
fair-rose
fair-rose5mo ago
if i wanted to minimize the number of fields watching i would have to watch them by their index. and i dont know how many there will be. it is also still slow if i try to watch only a.b.0.visa_req