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

v4 missing breaking changes #64

Closed renchap closed 5 years ago

renchap commented 5 years ago

I experienced 2 breaking changes when upgrading to v4. I am not sure they are worth maintaining compat for, but should be highlighted in release notes.

Child function arguments is always an object

With v3, I could do this:

<ReactResizeDetector handleWidth>
  width => <div>{width}</div>
</ReactResizeDetector>

This is no longer working with v4, you now need

<ReactResizeDetector handleWidth>
  ({width}) => <div>{width}</div>
</ReactResizeDetector>

Child components must not be a fragment

This was working before:

<ReactResizeDetector handleWidth>
  ({width, height}) => <><div /><div /></>
</ReactResizeDetector>

Now that the implementation no longer inserts a <div>, it is no longer working if the child function returns a fragment (which is implemented as an array iirc). It may be worth checking the return value and log an error in console if this happens.

ndelangen commented 5 years ago

I'm experiencing upgrade problems with Storybook as well, We're using Fragments and nothing is rendering.

renchap commented 5 years ago

Wrap the fragments into a <div> and you will get the previous behaviour (react-resize-detector used to insert this <div> for you)

clintharris commented 5 years ago

Similarly, there may need to be a "child component must not be an array" API change (or fix). The following (i.e., an array of children) results in an empty <div>:

<ReactResizeDetector>
  <Foo/>
  <Bar/>
</ReactResizeDetector>

This seems to be caused by React.isValidElement() returning false for arrays. [getRenderType()](https://github.com/maslianok/react-resize-detector/blob/master/src/components/ResizeDetector.js#L145), in turn, incorrectly returns 'parent' instead of 'child'.

Quick work-around is to wrap the children in <ChildWrapper> (or a similar function component that just returns props.children) so that React.isValidElement() returns true.

maslianok commented 5 years ago

Thanks everyone for your feedback! @renchap @ndelangen @clintharris

v4.0.5 released and next code snippets are working properly now:

1.

<ReactResizeDetector handleWidth>
  {({width, height}) => (
      <>
        <div />
        <div />
      </>
    )}
</ReactResizeDetector>

2.

<ReactResizeDetector handleWidth>
      <>
        <div />
        <div />
      </>
</ReactResizeDetector>

3.

<ReactResizeDetector>
  <Foo />
  <Bar />
</ReactResizeDetector>

I also updated documentation and v4 breaking changes to be more clear about Functional pattern width and height.