Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

useRef hook not triggering re-render

For some reason my test is not passing when using ref like this:

import React, { useRef } from "react";
import { waitForElement, render } from "@testing-library/react";

const MyComponent = props => {
  const elementRef = useRef(null);
  return (
    <div>
      <div ref={elementRef} />
      {elementRef.current && <div data-testid="test-div" />}
    </div>
  );
};

describe("MyComponent", () => {
  it("test-div should exist when the ref is set", async done => {
    const { getByTestId } = render(<MyComponent />);
    await waitForElement(() => getByTestId("test-div"));
  });
});

Any idea why this is not working?

like image 390
StrangeLoop Avatar asked Dec 05 '19 19:12

StrangeLoop


People also ask

Does useRef trigger re-render?

Conclusion. React's useRef hook is a great tool to persist data between renders without causing a rerender and to manipulate the DOM directly. It should only be used sparingly in situations where React doesn't provide a better alternative.

How do you force re-render React hooks?

Use the .forceUpdate() method to force a rerender and update the view. Once triggered, this method will update each child of the component. It's not recommended to use the component. forceUpdate() method unless you're sure you need it.

Does useRef notify when its content changes?

Keep in mind that useRef doesn't notify you when its content changes. Mutating the . current record field doesn't cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a callback ref instead.

Do hooks cause Rerender?

Every state change in a hook, whether it affects its return value or not, will cause the “host” component to re-render.


1 Answers

It's not the test that is not working, it's the rendering of the "test-div". If you tried rendering this component outside of the test, you would get the same result. As stated in the React Documentation:

Keep in mind that useRef doesn’t notify you when its content changes. Mutating the .current property doesn’t cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a callback ref instead.

This means that even though the ref gets set, the re-render never happens. You would need to trigger it through other means, perhaps by using a callback ref as stated above or creating a useEffect hook that reacts to the current value of the ref.

like image 171
Mikaela Avatar answered Oct 12 '22 14:10

Mikaela