diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js
index 8f1e8d971a..23df1d25bd 100644
--- a/packages/react-reconciler/src/ReactFiberBeginWork.js
+++ b/packages/react-reconciler/src/ReactFiberBeginWork.js
@@ -951,7 +951,7 @@ function mountLazyComponent(
null,
workInProgress,
Component,
- resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too,
+ resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
updateExpirationTime,
renderExpirationTime,
);
diff --git a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
index 52d2327d14..6efd405aba 100644
--- a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
@@ -632,6 +632,8 @@ describe('ReactLazy', () => {
expect(root).toMatchRenderedOutput('0');
}
+ // Note: all "with defaultProps" tests below also verify defaultProps works as expected.
+ // If we ever delete or move propTypes-related tests, make sure not to delete these.
it('respects propTypes on function component with defaultProps', async () => {
function Add(props) {
expect(props.innerWithDefault).toBe(42);
@@ -767,6 +769,54 @@ describe('ReactLazy', () => {
await verifyInnerPropTypesAreChecked(React.memo(Add));
});
+ it('uses outer resolved props for validating propTypes on memo', async () => {
+ let T = props => {
+ return ;
+ };
+ T.defaultProps = {
+ text: 'Inner default text',
+ };
+ T = React.memo(T);
+ T.propTypes = {
+ // Should not be satisfied by the *inner* defaultProps.
+ text: PropTypes.string.isRequired,
+ };
+ const LazyText = lazy(() => fakeImport(T));
+ const root = ReactTestRenderer.create(
+ }>
+
+ ,
+ {
+ unstable_isConcurrent: true,
+ },
+ );
+
+ expect(root).toFlushAndYield(['Loading...']);
+ expect(root).toMatchRenderedOutput(null);
+
+ // Mount
+ await Promise.resolve();
+ expect(() => {
+ root.unstable_flushAll();
+ }).toWarnDev(
+ 'The prop `text` is marked as required in `T`, but its value is `undefined`',
+ );
+ expect(root).toMatchRenderedOutput('Inner default text');
+
+ // Update
+ root.update(
+ }>
+
+ ,
+ );
+ expect(() => {
+ root.unstable_flushAll();
+ }).toWarnDev(
+ 'The prop `text` is marked as required in `T`, but its value is `null`',
+ );
+ expect(root).toMatchRenderedOutput(null);
+ });
+
it('includes lazy-loaded component in warning stack', async () => {
const LazyFoo = lazy(() => {
ReactTestRenderer.unstable_yield('Started loading');