Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Resolve defaultProps for lazy etc #1218

Merged
merged 1 commit into from
Nov 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions backend/attachRendererFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ var semver = require('semver');
var copyWithSet = require('./copyWithSet');
var getDisplayName = require('./getDisplayName');

// Taken from ReactElement.
function resolveDefaultProps(Component: any, baseProps: Object): Object {
if (Component && Component.defaultProps) {
// Resolve default props. Taken from ReactElement
const props = Object.assign({}, baseProps);
const defaultProps = Component.defaultProps;
for (const propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
return props;
}
return baseProps;
}

function getInternalReactConstants(version) {
var ReactTypeOfWork;
var ReactSymbols;
Expand Down Expand Up @@ -354,6 +370,14 @@ function attachRendererFiber(hook: Hook, rid: string, renderer: ReactRenderer):
break;
}

if (
props !== null &&
typeof fiber.elementType !== undefined &&
fiber.type !== fiber.elementType
) {
props = resolveDefaultProps(fiber.type, props);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could've put this into a more specific place, like Function + Class + ForwardRef + Memo or whichever ones support it. But I found this easier to read. The only way you could have a false positive here is if somebody assigned defaultProps to e.g. a context consumer. I think that's unlikely enough that it would be fine for DevTools to mistakingly resolve them for a type that doesn't support them — to keep the code readable.

Copy link
Contributor

Choose a reason for hiding this comment

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

This seems safe. I think any time fiber.type !== fiber.elementType, it's a lazy component.

}

if (Array.isArray(children)) {
let child = fiber.child;
while (child) {
Expand Down
21 changes: 21 additions & 0 deletions test/regression/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,27 @@ switch (major) {
</React.Suspense>
</Feature>
);

// lazy
const LazyWithDefaultProps = React.lazy(() => new Promise(resolve => {
function FooWithDefaultProps(props) {
return <h1>{props.greeting}, {props.name}</h1>;
}
FooWithDefaultProps.defaultProps = {
name: 'World',
greeting: 'Bonjour',
};
resolve({
default: FooWithDefaultProps,
});
}));
apps.push(
<Feature key="lazy" label="lazy" version="16.6+">
<React.Suspense fallback={<div>loading...</div>}>
<LazyWithDefaultProps greeting="Hello" />
</React.Suspense>
</Feature>
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice! ❤️

case 5:
case 4:
// unstable_Profiler
Expand Down