After React 18 upgrade resizeObserver.observe is not defined in custom Hook

481 Views Asked by At

After updating to React 18.2.0 I get the following error for my Hook:

Error: Uncaught [TypeError: resizeObserver.observe is not a function]

package.json

"react": "^18.2.0",
"react-dom": "^18.2.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.4.3",

My Hook:

import React from 'react';
import { config } from 'core/constants';
import { CreateResizeObserver } from 'common/utils';

export type ScrollActiveType = 'horizontal' | false;

export const useIsScrollActive = (
  ref: React.MutableRefObject<HTMLElement>,
  callback?: (scrollActive: ScrollActiveType) => void
) => {
  const [activeScroll, setActiveScroll] = React.useState<ScrollActiveType>(false);

  React.useEffect(() => {
    const { current } = ref;

    if (current) {
      const resizeObserver = CreateResizeObserver(() => {
        const isHorizontalScrollActive = current.scrollWidth > current.clientWidth;
        const currentActiveScroll = isHorizontalScrollActive ? 'horizontal' : false;
        setActiveScroll(currentActiveScroll);
        callback?.(currentActiveScroll);
      }, config.TIMING_THROTTLE_WAIT_LONG);

      resizeObserver.observe(ref.current);
      return () => resizeObserver.disconnect();
    }
  }, [ref?.current, callback]);

  return activeScroll;
};

resize.util.ts:

import throttle from 'lodash.throttle';
import { config } from 'core/constants';

/* istanbul ignore file */

/**
 * ResizeObserver factory
 */

export const CreateResizeObserver = (
  resizeCallback: (newWidth: number, newHeight: number) => void,
  callbackThrottleWait = config.TIMING_THROTTLE_WAIT_SHORT
) => {
  if (ResizeObserver) {
    // Throttled version of the resize callback
    const throttleResizeCallback = throttle(resizeCallback, callbackThrottleWait);

    return new ResizeObserver(([containerNode] = []) => {
      const contentBoxSize = containerNode?.contentBoxSize;
      const boxSize = Array.isArray(contentBoxSize) ? contentBoxSize[0] : contentBoxSize;
      throttleResizeCallback(Math.floor(boxSize?.inlineSize), Math.floor(boxSize?.blockSize));
    });
  } else return undefined;
};

With React 17 I did not have any problems and even upgrading from TypeScript v4 to v5 did not resolve this error and I do not what this is causing it.

Am I missing any version upgrades?

I am getting the error while running my unit test:

import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import 'core/i18n/i18n.config'; // [⚠] Make sure i18n instance is configured before anything else.
import { keyDictionary } from 'core/i18n/keys';

import { CustomerList } from 'pods/customer-list';
import { TranslatedKeysProvider } from 'core/i18n';
import * as api from './api/customer-list.api';

describe('Test suite for customer table', () => {
  it('should show customer, lab and integrators', async () => {
    // By mocking the api-request function we bypass jotai and react-query
    const getCustomersStub = jest.spyOn(api, 'getCustomerList').mockResolvedValue([
      {
        id: '12345',
        labs: [
          {
            id: '4321',
            address: { location: 'test location', country: '' },
            integratorEdges: [{ id: 'edge1' }, { id: 'edge2' }],
          },
        ],
      },
    ]);

    render(
      <TranslatedKeysProvider>
        <CustomerList />
      </TranslatedKeysProvider>
    );

    await waitFor(() => {
      expect(getCustomersStub).toHaveBeenCalled();
      screen.getByText(
        keyDictionary.customerList.list.titleGroups.customerGroup({ customerId: '12345' })
      );
      screen.getByText(keyDictionary.customerList.list.titleGroups.labGroup({ labId: '4321' }));
      screen.getByText('edge1');
      screen.getByText('edge2');
      // 2 instances on the table, 2 instances for tooltip, 1 per filter
      expect(screen.getAllByText('test location')).toHaveLength(5);
    });
  });
});
0

There are 0 best solutions below