title: Testing custom hook and getting "Warning: An update to TestHook inside a test was not wrapped in act
body: <p><strong>EDIT:</strong> I found a solution, coming from <a href="https://www.youtube.com/watch?v=PKUDcLGn-80" rel="nofollow noreferrer">this video</a> from Kent C. Dodds.</p>
  
  <p>Just wrap the jest.advanceTimersByTime calls in an act function.</p>
  
  <p>So this:</p>
  
  <pre class="lang-js prettyprint-override"><code>jest.advanceTimersByTime(510);
  </code></pre>
  
  <p>becomes:</p>
  
  <pre class="lang-js prettyprint-override"><code>act(()=&gt;jest.advanceTimersByTime(510));
  </code></pre>
  
  <hr>
  
  <p>I've implemented a simple custom hook in order to debounce a value update.</p>
  
  <p>Here is the code:</p>
  
  <pre class="lang-js prettyprint-override"><code>function useDebounce(value, delay) {
    const [debouncedValue, setDebouncedValue] = useState(value);
  
    useEffect(() =&gt; {
      const handler = setTimeout(() =&gt; {
        setDebouncedValue(value);
      }, delay);
  
      return () =&gt; {
        clearTimeout(handler);
      };
    }, [value, delay]);
  
    return debouncedValue;
  }
  </code></pre>
  
  <p>The client of this hook is something like this (very simplified):</p>
  
  <pre class="lang-js prettyprint-override"><code>function Search(props) {
    const [searchTerm, setSearchTerm] = useState('');
    const debouncedSearchTerm = useDebounce(searchTerm, 500);
  
    // doing something useful with debouncedSearchTerm....
    // ...
    // ...
  }
  </code></pre>
  
  <p>So, I'm trying to test the hook with the code below:</p>
  
  <pre class="lang-js prettyprint-override"><code>import { renderHook, act } from 'react-hooks-testing-library';
  import useDebounce from '../useDebounce';
  
  jest.useFakeTimers();
  
  it.only('should update value after specified delay', () =&gt; {
    const { result, rerender } = renderHook(
      ({ value, delay }) =&gt; useDebounce(value, delay),
      { initialProps: { value: '', delay: 500 } }
    );
  
    expect(result.current).toBe('');
    jest.advanceTimersByTime(510);
    expect(result.current).toBe('');
  
    rerender({ value: 'Hello World', delay: 500 });
  
    expect(result.current).toBe('');
    jest.advanceTimersByTime(498);
    expect(result.current).toBe('');
    jest.advanceTimersByTime(3);
    expect(result.current).toBe('Hello World');
  });
  </code></pre>
  
  <p>Although, the test passes, I get the following warning:</p>
  
  <pre><code>console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:102
  
  Warning: An update to TestHook inside a test was not wrapped in act(...).        When testing, code that causes React state updates should be wrapped into act(...):        act(() =&gt; {      /* fire events that update state */    });    /* assert on the output */        This ensures that you're testing the behavior the user would see in the browser. Learn more at.....       in TestHook        in Suspense
  </code></pre>
  
  <p>I get that if I'm about to call a function in order to update the internal state of the hook (e.g. increment() of a useCounter hook), I have to do it in an <em>act</em> function, as the documentation instructs.</p>
  
  <p>But, the useDebounce hook I've implemented changes state by an internal useEffect that runs whenever value or delay change.</p>
  
  <p>How can I get rid of this warning? Is it something wrong with my code? Am I forgetting to add  something in the test code?</p>
  
  <p>Please help!</p>