Preact: material-ui's Modal.js throwing out error with Preact

Created on 31 Jan 2019  路  10Comments  路  Source: preactjs/preact

Iam using material-ui for my Reactjs application. When I use Preact-compat as alias for "react" I get below error

Uncaught TypeError: Cannot read property 'hasOwnProperty' of undefined
    at getHasTransition (Modal.js?a179:62)
    at Function.getDerivedStateFromProps (Modal.js?a179:391)
    at renderComponent (preact.mjs?c80d:500)
    at renderComponent (preact.mjs?c80d:550)
    at renderComponent (preact.mjs?c80d:550)
    at renderComponent (preact.mjs?c80d:550)
    at renderComponent (preact.mjs?c80d:550)
    at renderComponent (preact.mjs?c80d:550)
    at setComponentProps (preact.mjs?c80d:471)
    at buildComponentFromVNode (preact.mjs?c80d:637)

What could be the possible issue?

compat in X known issue

Most helpful comment

Update: this is just silly use of props.children, they're assuming it's the only child. Material-UI should be using Children.only():

https://github.com/mui-org/material-ui/blob/next/packages/material-ui/src/Modal/Modal.js#L22

All 10 comments

@neetu-das Can you narrow it down to a snippet where the issue can be reproduced? CodeSandbox is a great tool to help you with that.

I'm guessing they're using Object.create(null) to build prototypeless objects somewhere. We used to in ~5.x, but that has since been removed - any chance you're using a really old version of Preact?

Update: this is just silly use of props.children, they're assuming it's the only child. Material-UI should be using Children.only():

https://github.com/mui-org/material-ui/blob/next/packages/material-ui/src/Modal/Modal.js#L22

@developit Should an issue be made in the Material-UI repo for this?

@roberthmiller yup, that's a bug in material-ui. They should use Children.only() like @developit suggested 馃憤

I'm not sure to follow. What are we doing wrong? We have the following prop types:

Modal.propTypes = {
  /**
   * A single child content element.
   */
  children: PropTypes.element.isRequired,
};

Do we have a reproduction example?


I love what you guys have been doing in https://github.com/developit/preact/releases/tag/10.0.0-alpha.1. I have tried to make it work with Next.js with no luck so far. I hope we can have a first class support for Preact on Material-UI side :).

@roberthmiller yup, that's a bug in material-ui. They should use Children.only() like @developit suggested +1

We already have a prop type validator for that like @oliviertassinari said. It's redundant in my opinion to guard against types that already trigger errors.

PropTypes.element does not accept multiple children.

@oliviertassinari That's awesome! We're very interested in making Preact work with Next.js 馃憤 If you run into any bugs please open an issue here :)

@eps1lon You argument makes sense and type checking should be enough in theory. The reconciler in (p)react treats both <div>foo</div> and [<div>foo</div>] the same way. Both will effectively render only one child. The latter will fail PropTypes.element though. Without seeing any code of the original poster we can only guess, but I'm assuming he ignored the warning or disabled preact/debug.

In our 8.x release line children are always an array and we jumped through hoops to convert it back to a non-array value in compat. This is not necessary anymore and material-ui should work right out of the box. If it doesn't we'd be really happy to fix any issues before going final 馃憤

To be honest all I really care about is that if props.children passes PropTypes.element.isRequired then props.children.props doesn't throw. I never used preact but it looks like I can access props.children.props safely even without any children at all: https://codesandbox.io/s/jp3j127vww

@developit
I'm also interested in some more details about

Update: this is just silly use of props.children [...]

Is this only silly if you don't have validation in place or silly in general?

@eps1lon The console.log only works because props.children defaults to being an array in Preact 8.x . So effectively the snippet does this [].props which is undefined because an array has no props property. The issue is that this [].props.hasOwnProperty("foo") will throw which seems to be the issue the original poster is experiencing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matuscongrady picture matuscongrady  路  3Comments

rajaraodv picture rajaraodv  路  3Comments

skaraman picture skaraman  路  3Comments

matthewmueller picture matthewmueller  路  3Comments

nopantsmonkey picture nopantsmonkey  路  3Comments