ctrlplusb / react-component-queries

Provide props to your React Components based on their Width and/or Height.
MIT License
183 stars 12 forks source link

responsive component inside of responsive component doesn't work #86

Open hoschi opened 7 years ago

hoschi commented 7 years ago

I have the case that I built a component which needs to be resizable on its own, but must use another component which is also resizable:

let InnerResizable = componentQueries(queryInner)(InnerDumb)

let OuterResizableDumb = ({fromQuery, otherProp}) => {
  return <div>
            {fromQuery &&
            <span>only visible when size fits</span>}
            <InnerResizable>see my prop {otherProp}</InnerResizable>
        </div>
}

let OuterResizable = componentQueries(queryOuter)(OuterResizableDumb)

On first render both components call their queries and resize right. On browser window resize the only component which updates (and calls their query) is the inner one. The outer one doesn't call their query and because of that it never changes its query result and isn't responsive.

By the time I developed the outer component, the inner one was not resizable. That way I know the outer version works fine without the inner one. As soon as I made the inner one also responsive the outer one stopped working.

For react-sizeme and react-component-queries I'm on the latest version. element-resize-detector is version 1.1.12 as dependency from another third party component. React is version 15.4.2.

ctrlplusb commented 7 years ago

Woah, very strange case!

Would you mind putting together an example via http://codesandbox.io/ and then I would be happy to review it for you.

hoschi commented 7 years ago

@ctrlplusb here is the example https://codesandbox.io/s/NkP3qy3rL

Sometimes the query of Outer calculates a new value one time after the resizing the window, sometimes it just works on first render as I described in my first post. Nevertheless it doesn't work beyond one change after the initial render. In index.js you can replace the import of Outer to get a "working" version. As a workaround I added a div around Inner.

For the record: My first example looked more than the version above https://codesandbox.io/s/Bp4D74gx which has more nodes in Outer to add some text to show which is the outer and which the inner component. It took me a good amount of the day to check that is really just the issue that the inner container gets returned without any wrapping element. In my real app Outer transforms some data into children for Inner so I can't combine Outer and Inner into one component.

ctrlplusb commented 7 years ago

Super helpful sandbox @hoschi! Thanks for putting this together.

I haven't looked into it yet, but my initial guess may be that the pure behaviour is causing an issue here. I'll need to investigate further.