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

Throw more specific error if passed undefined in React.cloneElement #12534

Merged
7 changes: 7 additions & 0 deletions packages/react/src/ReactElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import ReactCurrentOwner from './ReactCurrentOwner';

const hasOwnProperty = Object.prototype.hasOwnProperty;

const invariant = require('fbjs/lib/invariant');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you could use ES6 imports instead since the former ones do?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please!


const RESERVED_PROPS = {
key: true,
ref: true,
Expand Down Expand Up @@ -290,6 +292,11 @@ export function cloneAndReplaceKey(oldElement, newKey) {
* See https://reactjs.org/docs/react-api.html#cloneelement
*/
export function cloneElement(element, config, children) {
invariant(
!(element === null || element === undefined),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could just use a loose equality check here

element != null

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right yes, because the type conversion will catch undefined 👍

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, we've intentionally stopped using loose checks a while ago because they sometimes cause engine deoptimizations. I'd prefer strict ones.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gaearon didn't know that. We still have tons of places where we use loose equality checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gaearon okay gotcha, reverted that.

@aweary I can look into switching some over in a PR maybe? That should be pretty straightforward and I would love the opportunity to get more familiar with the codebase.

Copy link
Contributor

@aweary aweary Apr 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolevy I don't know, I'm not sure it's worth it? It could be helpful to make the changes and then somehow benchmark them. I'd also be interested in seeing a profile that shows the current deoptimizations and their impact as well. Making all the checks strict would increase the overall bundle size, so there are other costs to consider.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aweary hmmm okay, I’ll wait until a decision is made before I start on that then.

'Cannot clone a null or undefined element.'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something like React.cloneElement(...): The argument must be a React element, but you passed %s. and either null or undefined as second argument (invariant will interpolate it).

Copy link
Contributor Author

@wherestheguac wherestheguac Apr 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay thanks that’s cool, I’m going to read up on how invariant works for the future for sure. I’m also going to look at writing some tests.

Also wanted to ask if you have any input on this thread: #12534 (review)

);

let propName;

// Original props are copied
Expand Down