Repository: react-hook-form/react-hook-form
File: src/useForm.ts (TypeScript)

Code before:

    updateIsValidAndInputValue(name, ref);
  };

  const register: UseFormRegister<TFieldValues> = React.useCallback(
    (name, options = {}) => {
      const field = get(fieldsRef.current, name);

      set(fieldsRef.current, name, {
        _f: {
          ...(field && field._f ? field._f : { ref: { name } }),
          name,
          mount: true,
          ...options,
        },
      });
      namesRef.current.mount.add(name);
      !field && updateIsValidAndInputValue(name);

      return isWindowUndefined
        ? ({ name: name as InternalFieldName } as UseFormRegisterReturn)
        : {
            name,
            onChange: options.onChange
              ? (event: any) => {
                  const result = handleChange(event);
                  options.onChange && options.onChange(event);

                  return result;
                }
              : handleChange,
            onBlur: options.onBlur
              ? (event: any) => {
                  const result = handleChange(event);
                  options.onBlur && options.onBlur(event);

                  return result;
                }
              : handleChange,
            ref: (ref: HTMLInputElement | null): void => {
              if (ref) {
                registerFieldRef(name, ref, options);
              } else {
                const field = get(fieldsRef.current, name, {}) as Field;
                const shouldUnmount =
                  shouldUnregister || options.shouldUnregister;

                if (field._f) {
                  field._f.mount = false;
                  // If initial state of field element is disabled,
                  // value is not set on first "register"

Review comment (suggestion):
per provided examples, I am calling react-hook-form handler first, and then the custom one, not sure if it makes any difference?

Maybe we can just do:
```typescript
options.onChange(event);
return handleChange(event);
```


Code after:
import * as React from 'react';

import { createFormControl } from './logic/createFormControl';
import getProxyFormState from './logic/getProxyFormState';
import shouldRenderFormState from './logic/shouldRenderFormState';
import {
  FieldErrors,
  FieldNamesMarkedBoolean,
  FieldValues,
  FormState,
  UseFormProps,
  UseFormReturn,
} from './types';

export function useForm<
  TFieldValues extends FieldValues = FieldValues,
  TContext extends object = object,
>(
  props: UseFormProps<TFieldValues, TContext> = {},
): UseFormReturn<TFieldValues, TContext> {
  const _formControl = React.useRef<
    UseFormReturn<TFieldValues, TContext> | undefined
  >();
  const [formState, updateFormState] = React.useState<FormState<TFieldValues>>({
    isDirty: false,
    isValidating: false,
    dirtyFields: {} as FieldNamesMarkedBoolean<TFieldValues>,
    isSubmitted: false,
    submitCount: 0,
    touchedFields: {} as FieldNamesMarkedBoolean<TFieldValues>,
    isSubmitting: false,
    isSubmitSuccessful: false,
    isValid: false,
    errors: {} as FieldErrors<TFieldValues>,
  });

  if (_formControl.current) {
    _formControl.current.control._updateProps(props);
  } else {
    _formControl.current = {
      ...createFormControl(props),
      formState,
    };
  }

  const control = _formControl.current.control;

  React.useEffect(() => {
    const formStateSubscription = control._subjects.state.subscribe({
      next(formState) {
        if (shouldRenderFormState(formState, control._proxyFormState, true)) {
          control._formState = {
            ...control._formState,
            ...formState,
          };

          updateFormState({ ...control._formState });
        }
      },
    });

    return () => {
      formStateSubscription.unsubscribe();
    };
  }, [control]);

  React.useEffect(() => {
    if (!control._stateFlags.mount) {
      control._proxyFormState.isValid && control._updateValid();
      control._stateFlags.mount = true;
    }
    if (control._stateFlags.watch) {
      control._stateFlags.watch = false;
      control._subjects.state.next({});
    }
    control._removeFields();
  });

  _formControl.current.formState = getProxyFormState(
    formState,
    control._proxyFormState,
  );

  return _formControl.current;
}