Question: I am trying to test a custom hook using `@testing-library/react-hooks` but I have trouble testing the dependency. Let's use `useEffect` as an example:

```
import { renderHook } from '@testing-library/react-hooks';
import { useEffect } from 'react';

test('test dependency', () => {
  const callback = jest.fn((value: number) => {});
  let currentValue = 5;

  renderHook(() => useEffect(() => callback(currentValue), [currentValue]));
  expect(callback).toBeCalledTimes(1);
  expect(callback).toHaveBeenLastCalledWith(5);

  renderHook(() => useEffect(() => callback(currentValue), [currentValue]));
  expect(callback).toBeCalledTimes(1); // error here: called 2 times in reality
  expect(callback).toHaveBeenLastCalledWith(5);

  currentValue = 6;
  renderHook(() => useEffect(() => callback(currentValue), [currentValue]));
  expect(callback).toBeCalledTimes(2);
  expect(callback).toHaveBeenLastCalledWith(6);
});

```

Expected behaviour: `useEffect` is not called again with the same dependency list.

Actual behaviour: `useEffect` is called every time, probably because the context is destroyed and re-created betweeb `renderHook`.

I also tried putting the render method into a constant like this:

```
const myHook = () => useEffect(() => callback(currentValue), [currentValue]);
renderHook(myHook);

```

But no luck. Is there any way that I can test whether or not the dependency list works correctly?

Answer: 
It's expected that `renderHook` mounts on every call, doing the opposite would prevent it from being used with unrelated hooks.

As with React Testing Library `render`, [the result](https://react-hooks-testing-library.com/reference/api#renderhook-result) allows to control rendered instance, this includes `unmount` and `rerender`.

Additional values like `currentValue` can be passed the same way they would in a component, namely props object.

So it likely should be:

```
  let { rerender, unmount } = renderHook(
    ({ val }) => useEffect(() => callback(val), [val]),
    { initialProps: { val: 5 } }
  );

  expect(callback).toBeCalledTimes(1);
  expect(callback).toHaveBeenLastCalledWith(5);

  rerender({ val: 5 });

  expect(callback).toBeCalledTimes(1);
  expect(callback).toHaveBeenLastCalledWith(5);

  rerender({ val: 6 });

  expect(callback).toBeCalledTimes(2);
  expect(callback).toHaveBeenLastCalledWith(6);

```

Notice that the code tests React's own `useEffect` so it doesn't serve a practical purpose.
After some thinking, I came up with the following solution:

```
import { act, renderHook } from '@testing-library/react-hooks';
import { useEffect, useState } from 'react';

test('test dependency', () => {
  const callback = jest.fn((value: number) => {});
  const renderCounter = jest.fn();

  const { result } = renderHook(() => {
    const [{ value }, setValue] = useState({ value: 5 });
    renderCounter();
    useEffect(() => callback(value), [value]);
    return setValue;
  });

  expect(renderCounter).toHaveBeenCalledTimes(1);
  expect(callback).toBeCalledTimes(1);
  expect(callback).toHaveBeenLastCalledWith(5);

  act(() => result.current({ value: 5 }));
  expect(renderCounter).toHaveBeenCalledTimes(2);
  expect(callback).toBeCalledTimes(1);
  expect(callback).toHaveBeenLastCalledWith(5);

  act(() => result.current({ value: 6 }));
  expect(renderCounter).toHaveBeenCalledTimes(3);
  expect(callback).toBeCalledTimes(2);
  expect(callback).toHaveBeenLastCalledWith(6);
});

```

It's not that pretty but it works. The `renderCounter` is there to make sure that the inner hook is actually "re-rendering". For example, if you use `5` instead of `{value: 5}` for the state, then `act(() => result.current(5))` does not "re-render" the hook.