title: Jest + Formik - Warning: You called act(async () => ...) without await
body: <p>I am struggling with <code>act</code> errors when it comes to testing my React Native application using <code>JEST</code> and <code>testing-library</code>.
  I have a simple Formik form and I am trying to test if the validation works.</p>
  <p><strong>My screen I am testing:</strong></p>
  <pre><code>const SignInScreen: React.FC = () =&gt; {
      const { translations } = useContext(LocalizationContext);
      const [signIn, { isLoading, isError }] = useSignInMutation();
  
      const initialValues: SignInRequest = {
          name: '',
          password: ''
      };
  
      const validationSchema = Yup.object({
          name: Yup.string()
              .required(translations['required'])
              .max(15, ({max}) =&gt; translations.formatString(
                  translations['validationNCharOrLess'], { n: max })),
          password: Yup.string()
              .required(translations['required'])
      });
  
      const handleSubmit = async (values: SignInRequest, formikHelpers: FormikHelpers&lt;SignInRequest&gt;) =&gt; {
          await signIn(values)
              .unwrap()
              .catch(e =&gt; {
                  if ('data' in e &amp;&amp; e.data &amp;&amp;
                      'errors' in e.data &amp;&amp; e.data.errors)
                  {
                      formikHelpers.setErrors(mapErrors(e.data.errors));
                  }
              })
      }
  
      return (
          &lt;SafeAreaView
              testID={tiConfig.SAFE_AREA_VIEW}
              style={{ flex: 1 }}&gt;
              &lt;View
                  testID={tiConfig.SIGN_IN_SCREEN}
                  style={styles.container}&gt;
                  &lt;View&gt;
                      &lt;Text&gt;{translations['signIn']}&lt;/Text&gt;
                      &lt;Formik
                          initialValues={initialValues}
                          validationSchema={validationSchema}
                          onSubmit={handleSubmit}&gt;
                          {
                              ({ values, errors, handleSubmit, handleChange }) =&gt; (
                                  &lt;View&gt;
                                      &lt;Input
                                          testID={tiConfig.SIGN_IN_USERNAME_INPUT}
                                          value={values.name}
                                          placeholder={translations['username']}
                                          onChangeText={handleChange('name')}
                                          errorMessage={errors.name} /&gt;
                                      &lt;Input
                                          testID={tiConfig.SIGN_IN_PASSWORD_INPUT}
                                          value={values.password}
                                          placeholder={translations['password']}
                                          onChangeText={handleChange('password')}
                                          errorMessage={errors.password}
                                          secureTextEntry /&gt;
                                      {
                                          isError ?
                                              &lt;View&gt;
                                                  &lt;Text testID={tiConfig.SIGN_IN_SERVER_ERROR}&gt;
                                                      { translations['somethingWentWrongTryAgainLater'] }
                                                  &lt;/Text&gt;
                                              &lt;/View&gt;
                                              : null
                                      }
                                      &lt;Button
                                          testID={tiConfig.SIGN_IN_SUBMIT}
                                          title={translations['signIn']}
                                          onPress={handleSubmit}
                                          loading={isLoading} /&gt;
                                  &lt;/View&gt;
                              )
                          }
                      &lt;/Formik&gt;
                  &lt;/View&gt;
              &lt;/View&gt;
          &lt;/SafeAreaView&gt;
      );
  }
  </code></pre>
  <p><strong>My test:</strong></p>
  <pre><code>// tiConfig is a json with my test id constants
  test.only(&quot;Sign in username field validates correctly&quot;, async () =&gt; {
      const component = render(&lt;SignInScreen /&gt;);
  
      const usernameInput = await component.findByTestId(tiConfig.SIGN_IN_USERNAME_INPUT);   
      // A bit weird way to find the error text with a nesting but it works for now
      const errorMessage = usernameInput
          .parent!.parent!.parent!.parent!.parent!.parent!.findByType(Text);
      const submit = component.getByTestId(tiConfig.SIGN_IN_SUBMIT);
  
      fireEvent.press(submit);
      await waitFor(() =&gt; expect(errorMessage.props.children).toBe(translations.required));
      fireEvent.changeText(usernameInput, &quot;username&quot;);
      await waitFor(() =&gt; expect(errorMessage).toBeEmpty());
      fireEvent.changeText(usernameInput, &quot;toolongusernameshouldntbeallowed&quot;);
      await waitFor(() =&gt; expect(errorMessage).not.toBeEmpty());
  });
  </code></pre>
  <p><strong>Warning:</strong></p>
  <pre><code>Warning: You called act(async () =&gt; ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () =&gt; ...);
  
        at registerError (node_modules/react-native/Libraries/LogBox/LogBox.js:172:15)
        at errorImpl (node_modules/react-native/Libraries/LogBox/LogBox.js:58:22)
        at console.Object.&lt;anonymous&gt;.console.error (node_modules/react-native/Libraries/LogBox/LogBox.js:32:14)
        at printWarning (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:68:30)
        at error (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:44:5)
        at node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15297:13
        at tryCallOne (node_modules/promise/lib/core.js:37:12)
  </code></pre>
  <p>I get this warning <strong>3 times</strong>
  Without <code>waitFor</code> my test doesn't pass as all of the <code>expect</code> need to be awaited. I tried to wrap <code>fireEvent</code>s in <code>act</code> as well, but according to few blog posts from Kent C. Dodds we shouldn't wrap <code>fireEvent</code> in <code>act</code> so although the test passes I still get the warnings.
  Any ideas how I can fix this?</p>