question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

formState.dirty not being updated after field's value changes with @testing-library/react

See original GitHub issue

Describe the bug

react-hook-form does not update formState parameters when fields get updated inside testing-library tests.

To Reproduce

You can reproduce it with the following code:

// form.js
import React from 'react';

import {useState} from 'react';

import useForm from 'react-hook-form';

const Form = ({submit}) => {
  const { register, handleSubmit, formState } = useForm({mode: 'onChange'});
  
  const [val, setVal] = useState(false);

  const onSubmit = (data) => {
    setVal(true);
    // formState.dirty === false should be true
    submit(formState.dirty)
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input data-testid="myinput" name="myinput" ref={register} /> {/* register an input */}
      
      <button type="submit" data-testid="login-submit"> Login </button>

      {val && <div data-testid="my-res"> Value Set! </div>}
    </form>
  );
};

export default Form;
// form.spec.js
import React from 'react';

import { render, cleanup, fireEvent } from '@testing-library/react';

import Form from './form';

require('mutationobserver-shim');

afterEach(cleanup);

describe('form', () => {

  it('tells when submission is dirty', async () => {

    const submit = jest.fn()
    const { getByTestId, findByTestId } = render(<Form  submit={submit}/>);

    const myinput = getByTestId("myinput");

    const submitButon = await findByTestId('login-submit');

    fireEvent.change(myinput, { target: { value: 'set random input' } });

    fireEvent.click(submitButon);

    await findByTestId('my-res')

   // it's being called with false
    expect(submit).toHaveBeenCalledWith(true)
  });

});

Expected behavior When submitting, formState.dirty should be true as we’ve changed the input value.

Desktop (please complete the following information):

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:4
  • Comments:16 (8 by maintainers)

github_iconTop GitHub Comments

5reactions
bluebill1049commented, Oct 9, 2019

I think if you change fireEvent.input should work for you.

4reactions
MerlinMasoncommented, Dec 15, 2021

I’ve spent half of today battling with a similar issue, turns out it was painfully simple… hopefully this helps someone else!

In my case I was toggling a checkbox and then trying to check the validation state. Like so:

fireEvent.click(getByLabelText("My label"));
// attempt to test formState here

However nothing on the formState was being updated. The way my form was setup was to only validate onBlur. Additionally, validation seems to happen asynchronously, so wrapping any further expects in waitFor seemed to do the trick.

fireEvent.click(getByLabelText("My label"));
fireEvent.blur(getByLabelText("My label"));

waitFor(()=> {
    // test changes to formState here
})
Read more comments on GitHub >

github_iconTop Results From Across the Web

React-hook-form doesn't set isDirty to false when back to initial ...
When you change back to the original value, isDirty remains true, because ALL of the default values don't match the form input values...
Read more >
useFormState - Simple React forms validation
Dirty fields will not represent as isDirty formState, because dirty fields are marked field dirty at field level rather the entire form.
Read more >
Testing React Hook Form With React Testing Library
We'll use React Testing Library (RTL) as a testing framework of choice, since it works really well with the Hook Form and is...
Read more >
Firing Events - Testing Library
change event on an input of type "date". Otherwise the element will not // reflect the changed value. // Invalid: fireEvent.change(input ...
Read more >
Examples - Final Form Docs
Uses the built-in React inputs: input , select , and textarea to build a form with no validation. ... Strongly Typed Form and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found