Skip to content

Conversation

@Han5991
Copy link
Contributor

@Han5991 Han5991 commented Oct 8, 2025

⏺ 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

  • Removed unnecessary React.useMemo wrapper around the control.register call in src/useFieldArray.ts:112-118

Changes

  • src/useFieldArray.ts: Simplified rules registration by removing useMemo wrapper
  • src/tests/useFieldArray.test.tsx: Added comprehensive test case validating that rules from parent component are properly enforced

Copy link
Member

@bluebill1049 bluebill1049 left a 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!

Comment on lines 112 to 116
rules &&
(control as Control<TFieldValues, any, TTransformedValues>).register(
name as FieldPath<TFieldValues>,
rules as RegisterOptions<TFieldValues>,
);
Copy link
Member

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 = rules

Copy link
Contributor Author

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?

Copy link
Member

@bluebill1049 bluebill1049 Oct 8, 2025

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

re-ran the test suite, but it still fails.

Copy link
Contributor Author

@Han5991 Han5991 Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
  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?

Copy link
Member

@bluebill1049 bluebill1049 left a 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

@bluebill1049 bluebill1049 merged commit ded8e11 into react-hook-form:master Oct 9, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

issue: Regression useFieldArray rule attribute not being respected when passed from parent

2 participants