How to Mock useLayoutEffect Hook in React

Testing React components that utilize the useLayoutEffect hook in testing environments like Jest often triggers console warnings, specifically the “useLayoutEffect does nothing on the server” warning. This article provides a quick, straightforward guide on how to mock the useLayoutEffect hook to eliminate these warnings and ensure your unit tests run smoothly.

Why Mock useLayoutEffect?

The useLayoutEffect hook fires synchronously after all DOM mutations but before the browser paints. Because test runners like Jest run in a simulated browser environment (JSDOM) powered by Node.js, React detects that it is not running in a real browser and outputs a warning.

To prevent this clutter in your test suite, you can mock useLayoutEffect to behave exactly like useEffect during testing.

The cleanest way to handle this warning is by mocking the hook globally in your Jest setup file (usually jest.setup.js or setupTests.js). This applies the fix to all tests automatically.

Add the following line to your Jest setup file:

import React from 'react';

jest.spyOn(React, 'useLayoutEffect').mockImplementation(React.useEffect);

If you only want to apply this mock to a specific test file, you can place this exact code block at the very top of that specific test file.

Method 2: Creating a Custom Safe Hook

If you prefer not to touch your Jest configuration, you can solve the issue within your source code by creating a custom hook that conditionally uses useEffect or useLayoutEffect depending on the runtime environment.

Create a helper hook:

import { useEffect, useLayoutEffect } from 'react';

export const useSafeLayoutEffect = 
  typeof window !== 'undefined' ? useLayoutEffect : useEffect;

Inside your components, import and use useSafeLayoutEffect instead of React’s default useLayoutEffect. This naturally bypasses the warning during server-side rendering and testing environments without requiring Jest mocks.

Method 3: Inline Jest Mocking

If you are using standard jest.mock to mock module-level exports, you can mock the React module directly at the top of your test file:

import React from 'react';

jest.mock('react', () => ({
  ...jest.requireActual('react'),
  useLayoutEffect: jest.requireActual('react').useEffect,
}));

This approach overrides useLayoutEffect with useEffect specifically for the test file it is declared in, allowing your tests to render components without console errors.