perf: stabilize useConditionalField default values with useRef and replace Zod superRefine with declarative unions for performance

This commit is contained in:
Firman Ramdhani
2026-06-15 23:06:58 +07:00
parent 50cce32ada
commit f9a6519da4
3 changed files with 104 additions and 21 deletions
+9 -3
View File
@@ -1,4 +1,4 @@
import { useEffect } from 'react';
import { useEffect, useRef } from 'react';
import type { UseFormSetValue, UseFormUnregister, UseFormClearErrors, FieldValues, Path } from 'react-hook-form';
export interface UseConditionalFieldOptions<TFieldValues extends FieldValues> {
@@ -33,12 +33,19 @@ export function useConditionalField<TFieldValues extends FieldValues>(
const config = options;
// Stabilize defaultValue using useRef to prevent infinite render loops
// if developers pass inline arrays/objects (e.g. defaultValue: [])
const defaultValueRef = useRef(defaultValue);
useEffect(() => {
defaultValueRef.current = defaultValue;
}, [defaultValue]);
useEffect(() => {
// When the condition evaluates to false, we execute the cleanup logic
if (!condition) {
// 1. Reset the field value. We use a stable empty state (like '' instead of undefined)
// to prevent uncontrolled component fallback in the React UI. We also force RHF to sync.
const targetValue = config.defaultValue !== undefined ? config.defaultValue : ('' as any);
const targetValue = defaultValueRef.current !== undefined ? defaultValueRef.current : ('' as any);
config.setValue(config.name, targetValue, {
shouldDirty: true,
shouldTouch: true,
@@ -63,7 +70,6 @@ export function useConditionalField<TFieldValues extends FieldValues>(
setValue,
unregister,
clearErrors,
defaultValue,
mode
]);
}