react-hook
react-hook copied to clipboard
Resize observer not firing
//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.