formState.dirty not being updated after field's value changes with @testing-library/react
See original GitHub issueDescribe 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):
- @testing-library/react@9.3.0
- Version “3.23.18-beta.2”
Issue Analytics
- State:
- Created 4 years ago
- Reactions:4
- Comments:16 (8 by maintainers)
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

I think if you change
fireEvent.inputshould work for you.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:
However nothing on the
formStatewas being updated. The way my form was setup was to only validate onBlur. Additionally, validation seems to happen asynchronously, so wrapping any further expects inwaitForseemed to do the trick.