-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
🐞 fix: respect parent-provided useFieldArray rules (#13082) #13083
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🐞 fix: respect parent-provided useFieldArray rules (#13082) #13083
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the PR!
src/useFieldArray.ts
Outdated
| rules && | ||
| (control as Control<TFieldValues, any, TTransformedValues>).register( | ||
| name as FieldPath<TFieldValues>, | ||
| rules as RegisterOptions<TFieldValues>, | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we try to use rules with ref instead? would be good if we can still keep the memo.
const rulesRef = useRef(rules)
reulsRef.current = rulesThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const rulesRef = React.useRef(rules);
rulesRef.current = rules;
control._names.array.add(name);
rulesRef.current &&
(control as Control<TFieldValues, any, TTransformedValues>).register(
name as FieldPath<TFieldValues>,
rulesRef.current as RegisterOptions<TFieldValues>,
);rulesRef as suggested. This keeps the latest rules value in a ref while preserving memoization. Test passes. Does this look right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const rulesRef = React.useRef(rules);
rulesRef.current = rules;
const _actioned = React.useRef(false);
control._names.array.add(name);
React.useMemo(
() =>
rules &&
(control as Control<TFieldValues, any, TTransformedValues>).register(
name as FieldPath<TFieldValues>,
rulesRef.current as RegisterOptions<TFieldValues>,
),
[control, name],
);what about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
React.useMemo(
() =>
rules &&
(control as Control<TFieldValues, any, TTransformedValues>).register(
name as FieldPath<TFieldValues>,
rules as RegisterOptions<TFieldValues>,
),
// eslint-disable-next-line react-hooks/exhaustive-deps
[control, name, fields.length, rules],
);What do you think about this code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ty very much for the fix

⏺ Summary
fixes #13082
Problem
When rules were passed to useFieldArray from a parent component, they were wrapped in React.useMemo without proper dependencies, causing the rules to be registered only once during initial render. If the rules object reference changed (e.g., created inline or from useMemo in parent), the validation would not update
properly.
Solution
Changes