Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resize observer not firing #303

Open
AdamKasela opened this issue Aug 30, 2023 · 1 comment
Open

Resize observer not firing #303

AdamKasela opened this issue Aug 30, 2023 · 1 comment
Labels
question Further information is requested

Comments

@AdamKasela
Copy link

AdamKasela commented Aug 30, 2023

//useElementSize.tsx
import useResizeObserver from '@react-hook/resize-observer';
import { MutableRefObject, useLayoutEffect, useState } from 'react';

interface Size {
  width: number;
  height: number;
}

export default function useElementSize<T extends HTMLElement = HTMLDivElement>(
  target: MutableRefObject<T | null>,
) {
  const [size, setSize] = useState<Size>({
    width: 0,
    height: 0,
  });

  useLayoutEffect(() => {
    target.current && setSize(target.current.getBoundingClientRect());
  }, [target]);

  useResizeObserver(target, (entry) => {
    setSize(entry.contentRect);
  });

  return size;
}
//Other component
import { Box } from '@mui/material';
import clsx from 'clsx';
import { Fragment, useRef, useState } from 'react';
import { useInView } from 'react-intersection-observer';
import Config from '../../../../config';
import { ViewerMode } from '../../../../models';
import { ScannedPage } from '../../../../models/generated';
import useScrollNavigationStore from '../../../../stores/ScrollNavigationStore';
import style from './DocumentPage.module.scss';
import { Word } from '../../../ui';
import useSize from '@react-hook/size';
import useElementSize from '../../../../hooks/useElementSize';

type DocumentPageProps = {
  docIndex: number;
  docPageIndex: number;
  viewerMode: ViewerMode;
  scannedPage: ScannedPage;
  selected?: boolean;
};

export const DocumentPage = ({
  docIndex,
  docPageIndex,
  viewerMode,
  scannedPage,
  selected = false,
}: DocumentPageProps) => {
  const documentPageSrc = `${Config.API_BASE_URL}/api/v1/core/file/${encodeURIComponent(
    scannedPage.imagePath,
  )}/lob/Personenversicherung`;
  const [isLoading, setIsLoading] = useState(true);
  const setSelectedIndexes = useScrollNavigationStore(
    (state) => state.setSelectedIndexes,
  );
  const imgRef = useRef<HTMLImageElement>(null);
  const { width, height } = useElementSize<HTMLImageElement>(imgRef);
  const widthRatio = width / scannedPage.width;
  const heightRatio = height / scannedPage.height;
  const { ref, inView } = useInView({
    triggerOnce: true,
    rootMargin: '0px 0px 90% 0px',
    threshold: 0.8,
  });

 
  return (
    <Box
      ref={ref}
      component={'div'}
      data-inview={inView}
      alignItems={'center'}
      justifyContent={'center'}
      className={clsx(style.documentWrapper, {
        [style.selected]: selected,
        [style.loading]: isLoading,
      })}
      sx={{ minHeight: '200px' }}
      onClick={() => handleClick([docIndex, docPageIndex], viewerMode)}
    >
      {inView ? (
        <div style={{ position: 'relative' }}>
          <img
            ref={imgRef}
            loading="lazy"
            width={scannedPage.width}
            height={scannedPage.height}
            src={documentPageSrc}
            alt="document"
            placeholder="document"
            draggable={false}
            style={{ width: '100%', height: '100%', userSelect: 'none' }}
            onLoad={() => handleImgLoad()}
            aria-hidden="true"
          />
          {viewerMode === ViewerMode.Viewer &&
            scannedPage.scannedLineBoxes?.map((line, lineIndex) => {
              return (
                <Fragment key={`Line${lineIndex}`}>
                  {line.words?.map((word, wordIndex) => {
                    return (
                      <Box
                        key={`Line${lineIndex}-Word${wordIndex}`}
                        top={`${word.y * heightRatio}px`}
                        left={`${word.x * widthRatio}px`}
                        width={`${word.width * widthRatio}px`}
                        height={`${word.height * heightRatio}px`}
                        margin={0}
                        position={'absolute'}
                        color={'transparent'}
                        border={'1px solid red'}
                      >
                        <Word
                          height={`${word.height * heightRatio}px`}
                          lineHeight={`${word.height * heightRatio}px`}
                        >
                          {word.text}
                        </Word>
                      </Box>
                    );
                  })}
                </Fragment>
              );
            })}
        </div>
      ) : null}
    </Box>
  );
};

I'm not sure why but Resize observer is not triggering at all. I tried using useSize hook implemented from this lib but this also is not working. Can you pls help me somebody ? What can cause this issue ? When I use target.current in dependency array of useLayoutEffect the initial width and height get set but consecutive resizing doesn't trigger anything.

@jaredLunde
Copy link
Owner

jaredLunde commented Aug 25, 2024

Very straightforward: your img element enters and leaves the DOM and the hook doesn't use ref.current as a dependency, just ref. You need to set the ref via useState instead of useRef in this case, as shown in the example here: https://codesandbox.io/s/react-hookresize-observer-example-ft88x

@jaredLunde jaredLunde added the question Further information is requested label Aug 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants