maslianok / react-resize-detector

A Cross-Browser, Event-based, Element Resize Detection for React
http://maslianok.github.io/react-resize-detector/
MIT License
1.25k stars 91 forks source link

width and height undefined if "ref div" is located after conditional rendering #178

Closed Capsicum42 closed 1 year ago

Capsicum42 commented 3 years ago

Hi Masianok,

thanks for the library.

I have the following problem:

const [result, reexecuteQuery] = useGetMissionsTimeLineQuery({
    variables: {
      id: "7d99fb36-936b-4f40-81e6-0cbfce5190da",
      isActive: true,
      memberId: "xxxx",
    },
  });
  const { data, error, fetching } = result;
  const onResize = useCallback(
    () => {
       console.log('resize')
    },
    [],
  )

  const { width, height,ref } = useResizeDetector({onResize});
...
return <div ref={ref}>{`${width}x${height}`}</div>
`

work accordingly description.

But if I add: conditions before the final div:

  if (!data) return <div>Loading</div>;
  if (fetching) return <div>Loading</div>;
  if (error) return <div>error</div>;
  return <div ref={ref}>{`${width}x${height}`}</div>

witdhand height are undefined for ever.

Is it a bug, or did I use the library wrong ? Thanks for your help.

andremiguelaa commented 3 years ago

Same issue here, I ended up creating an additional component to wrap the content of the last return

Capsicum42 commented 3 years ago

I switched over to: https://airbnb.io/visx and used the component: <ParentSize> from https://airbnb.io/visx/docs/responsive

This workes well

andremiguelaa commented 3 years ago

those links don't work, mate

Capsicum42 commented 3 years ago

Thank for the info. I corrected the links.

madelineurl commented 2 years ago

Having the same issue. Delayed updating of ref from null (and width/height undefined) --> the currently rendered div (the div has appeared but onResize has not been triggered, even though skipOnMount is false). Only triggers when I switch to a different browser window then back to the current window, then works seamlessly after that

barbalex commented 2 years ago

This is pretty nerve racking. I have tried all kinds of settings (refreshMode, -rate, -Options). Without any I get undefined and it stays that way. With

{
    refreshMode: 'debounce',
    refreshRate: 300,
    refreshOptions: { trailing: true },
  }

the component renders twice after receiving the width. But id does return a width value.

So:

  1. does not work without options
  2. renders twice instead of once

I have conditional rendering too. But removing it seemed to change nothing.

RandScullard commented 2 years ago

Conditional rendering definitely causes problems with react-resize-detector. In my testing, if the referenced element doesn't exist when useResizeDetector is first called, you will never get a resize notification - even after the element is subsequently created. The solution that works for me is to split my component. Starting with @Capsicum42's original example:

  const { width, height, ref } = useResizeDetector({onResize});

  ...

  if (!data) return <div>Loading</div>;
  if (fetching) return <div>Loading</div>;
  if (error) return <div>error</div>;
  return <div ref={ref}>{`${width}x${height}`}</div>

Change it to:

function OuterComponent()
{
  if (!data) return <div>Loading</div>;
  if (fetching) return <div>Loading</div>;
  if (error) return <div>error</div>;
  return <InnerComponent/>;
}

function InnerComponent()
{
  const { width, height, ref } = useResizeDetector({onResize});
  return <div ref={ref}>{`${width}x${height}`}</div>
}

This way, the ref will always refer to a live element. This is a bit of a pain though - it would be nice if react-resize-detector could handle this situation without any special workaround.

barbalex commented 1 year ago

One and a half years after my above comment, I realized in a different project that width always was null and never updated. After an hour of debugging I found my above comment, added some options and bang - now it works.

This behavior is VERY unexpected.

maslianok commented 1 year ago

If anyone here is still interested in this library - this should be fixed in v9 :)

Are there any GitHub awards for the fastest fix or something like this?