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

Getting a "0" instead of my component. #28

Open
blechner opened this issue May 27, 2016 · 21 comments
Open

Getting a "0" instead of my component. #28

blechner opened this issue May 27, 2016 · 21 comments

Comments

@blechner
Copy link

I've just found this and I am trying to use it. I am having the same problem as @jdelafon in issue #1 . I wrapped my component with Dimensions()(MyComponent) and all I see is a "0" rendered instead of MyComponent. The parent component has width specified and I can access this.props.containerWidth in MyComponent's render() method, but I don't understand why I am getting a "0" div. If manually resize the browser window, then I can see MyComponent rendered normally. Am I missing something? Should I add code to force a resize event?!

@gmaclennan
Copy link
Member

hard to tell without seeing the code.

@blechner
Copy link
Author

ok, here are the chunks that I've changed to add react-dimensions:

In the beginning of the file that defines my component, I added this import:

import dimensions from 'react-dimensions';

and in the end, in the part where I export the component, I wrapped it in a dimensions()() call:

export default dimensions()(CarouselImage);

and, in the render method, I added a console.log() to make sure that I am getting the width correctly from the parent component (which has the width specified in css):

  render() {
    console.log(this.props.containerWidth);

Turns out that console.log() prints the width correctly, the only problem is that there is a "0" div instead of my component when I inspect the element using chrome developer tools.
Then when I manually resize the browser window, my component renders correctly, but I can't expect the user to manually resize the browser window...

@gmaclennan
Copy link
Member

Hi @blechner thanks for sharing more info but it's almost impossible to help solve the problem if I can't reproduce it. If you can share some code that I can run and get the same problem then I can maybe tell if the bug is in react-dimensions.

@blechner
Copy link
Author

I'll see if I can isolate the code and then share...

@mcadelago
Copy link

I'm getting the same issue. I'll see if I can post some code snippets later

@mcadelago
Copy link

I think this is the situation that's causing the issue for us:

renderWidget(widgetName) {
    let Widget = this.props.flow.widgets[widgetName]

    return (
        <Widget />
    )
  },

The Widget component in this render method is what is wrapped in Dimensions. We have it stored in an object, which is where we render it from. Technically, Widget in this case is an arrow function that returns the component.

We're using Dimensions in a few other areas of the app and it works perfectly, but this is where we see the problems. FYI one thing that's interesting is it only seems to happen when we're using flexbox on the outer components (sometimes), and sure enough if you resize the window it starts rendering the component again.

@gmaclennan
Copy link
Member

Here's what I recommend for troubleshooting: using the chrome web inspector check the size of the wrapper div that react-dimensions creates when the app is in the state that renders 0. If this is a flex box issue then you probably need to override the styling of that div by passing the containerStyle option to react-dimensions - when it is in a flexbox layout the default style of width: 100%; height: 100%; will not fill the container, and instead render a div with no height/width, which I think might be the issue that results in 0 being rendered. In the web inspector change in style of the wrapper div so that it fills the containing element, and then use that as your override style.

@blechner
Copy link
Author

I've just tried to use Dimensions in a public git project I have so I could show you, but it worked perfectly there...
I'll try your suggestion in the project where the problem is happening... thanks.

@blechner
Copy link
Author

blechner commented May 27, 2016

I've inspected the element and saw this:

<div style="width: 100%; height: 100%; padding: 0px; border: 0px;">0</div>

Not sure if I understood your suggestion... so I need to pass containerStyle to react-dimensions? What should I pass as containerStyle? I am not an expert in css. How do I know if my problem is this "flexbox" that you mentioned?

@gmaclennan
Copy link
Member

react-dimensions is designed to fill the width and height of its container and pass that width and height as pixels as the props to the Component that you wrap. It does this in a fairly dumb way, by creating a div with width: 100%; height: 100%; and measuring that. In most situations this CSS will make it fill to the width and height of the container, but in some layouts, in particular flex box layout, it won't work, and the div ends up having no height or width, and in this situation react-dimensions just renders a 0 (it actually renders null). I think I need to change this behaviour so it is clearer what is going wrong.

What you need to look for in the inspector is the rendered height and width of the div. If it does not have a height or width, that is the problem. In most cases where this 0 problem has come up, it is a CSS issue, not a react-dimensions issue, although there might be ways of making this error more obvious. If the container div is not getting any height or width because of a css issue, then you need to fix it by overriding the default css on the div with containerStyle. As all sites and layouts are different, it's hard to know. If you are rendering this component as part of a site/layout that uses flexbox, then it is the likely cause of this issue, and something like Dimensions({containerStyle: {flex: 1}})(MyComponent) is probably what you want. But that's entirely dependent on how you are using this in your site.

@gmaclennan
Copy link
Member

If you're still having problems try the latest version on master which rather than measuring the wrapper div it reaches up and measures the parent node.

@blechner
Copy link
Author

blechner commented Jun 3, 2016

I've just tried the latest version but the problem is still there.
But don't worry, maybe this is because my use case is not one that this lib can solve. As I mentioned, it worked when I tested in another project.
My team and I are investigating other ways to solve the problem of finding out the dimensions in px using DOM event listeners (https://facebook.github.io/react/tips/dom-event-listeners.html)
Thanks for your help. If no one else is complaining about this issue, you can close it.

@nhducit
Copy link

nhducit commented Jul 7, 2016

I got this issue too and I'm using flex-box to style the container and react-dimension return 0px height but actually the container have 598px of height.

My application have 2 route, one route contains normal form and the second contains the fixed-data-table with react-dimension, if I start from "form" page then change route to the second page, everything is fine. But if I enter the second route for the first time I load my application react-dimension will return 0px of height

@gmaclennan
Copy link
Member

@nhducit as with previous times this issue has arisen, it is impossible to fix without sharing code that replicates the problem.

@nhannh23
Copy link

Hi @gmaclennan
I'm using react-dimensions to wrap my component. It works perfectly in storybook. My component is rendered. But it fails in the unit test that i created for that component. Here is the test.

import * as React from 'react'
import * as test from 'tape'
import { mount } from 'enzyme'
import MyComponent from '../../MyComponent/MyComponent'

const fakeData = {
  data: [
    {
      'id': 1,
      'name': 'Gary',
      'date_of_birth': '26/01/2016',
      'email': 'gprice0@yahoo.co.jp',
      'gender': 'Male',
    },
  ],
}
test.only('MyComponent renders', function (t) {
  const component = mount(<MyComponent data={fakeData.data} />)
  t.equal(component.html(), '', 'should render my component')
  t.end()
})

In the test console, it always render:
'<div style=\"width: 100%; height: 100%; padding: 0px; border: 0px;\">0</div>'

I tried your suggetion as:
ReactDimensions({containerStyle: {display: 'flex', flex: 1}})(MyComponent)

It becomes like this:
'<div style=\"display: flex; flex: 1 1 0%;\">0</div>'

Any help pls?

@conor909
Copy link

conor909 commented Oct 24, 2016

I'm getting the same issue, but I'm not using this lib. I'v created a custom tooltips component that wraps around some other components or markup. If the child elements containers are floated left, then I get 0, if I remove the floats the components render fine (but without the layout I want)

           <div>
                <div>
                    <div style={labelStyle}>Editing chart:</div>
                </div>
                <div> 
                    <Tooltip content="Hello World" position="right">
                        <div> /* <---- if this has a float I get "0"  */
                            <input
                                type="text"
                                style={textInputStyle}
                                placeholder="placeholder"
                                value={this.state.value}
                                onBlur={this.handleBlur}
                                onChange={this.handleChange} />
                        </div>
                    </Tooltip>
                </div>
            </div>);

@jdelafon
Copy link

jdelafon commented Oct 24, 2016

@conor909 The "0" in this module is due to this line:

{(containerWidth || containerHeight) && <ComposedComponent ... />}

in render, which evaluates to 0 if one of the container dimensions is 0, and becomes "0" because it is the content of a <div> in JSX. So if you are not using react-dimensions, it may be that you wrote the same kind of code in your Tooltip; when you float the inner component, maybe the container width or height becomes zero.

For all other people having the issue, having a "0" content means that either containerWidth or containerHeight is zero.

@gmaclennan Maybe to prevent more people reporting this issue, a clearer message could replace the "0" when one of the dimensions is zero. Because there is no case where you want the actual "0" to appear in your browser anyway, so better replace it with something like "[zero-size-component]", or send a console warning.

@tomasswood
Copy link

Another option is to ensure that containerWidth and ContainerHeight are checked as a bool:

{(!!containerWidth || !!containerHeight) && <ComposedComponent ... />}

@gmaclennan
Copy link
Member

This would probably fix it: #64

Sorry I haven't really had any time to maintain this module, maintainers welcome! If someone tests that PR and it works I'll go ahead and merge, no time to test here. I based it on the v1.3.0 branch, is that what people are using? Or the v2 alpha?

@MarcusJay
Copy link

If you encounter this issue and aren't using react-dimensions, jdelafon's explanation above may still apply to you. It's not specific to this lib. Suppose you're loading data from a backend that returns booleans as 0 or 1 (e.g tinyInt). For example

  const showWarning = api.data.isInvalid || api.data.exceedsLimit
  {showWarning && 
  <Warning />
  }

showWarning may be 0 rather than false. Wrapping the expression in Boolean() will avoid unexpected int literals.

@Angela-Inniss
Copy link

Thank you @MarcusJay this was the solution to my problem!!! 🥇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants