| 10 | import {REACT_MEMO_TYPE} from 'shared/ReactSymbols'; |
| 11 | |
| 12 | export function memo<Props>( |
| 13 | type: React$ElementType, |
| 14 | compare?: (oldProps: Props, newProps: Props) => boolean, |
| 15 | ) { |
| 16 | if (__DEV__) { |
| 17 | if (type == null) { |
| 18 | console.error( |
| 19 | 'memo: The first argument must be a component. Instead ' + |
| 20 | 'received: %s', |
| 21 | type === null ? 'null' : typeof type, |
| 22 | ); |
| 23 | } |
| 24 | } |
| 25 | const elementType = { |
| 26 | $$typeof: REACT_MEMO_TYPE, |
| 27 | type, |
| 28 | compare: compare === undefined ? null : compare, |
| 29 | }; |
| 30 | if (__DEV__) { |
| 31 | let ownName; |
| 32 | Object.defineProperty(elementType, 'displayName', { |
| 33 | enumerable: false, |
| 34 | configurable: true, |
| 35 | get: function () { |
| 36 | return ownName; |
| 37 | }, |
| 38 | set: function (name) { |
| 39 | ownName = name; |
| 40 | |
| 41 | // The inner component shouldn't inherit this display name in most cases, |
| 42 | // because the component may be used elsewhere. |
| 43 | // But it's nice for anonymous functions to inherit the name, |
| 44 | // so that our component-stack generation logic will display their frames. |
| 45 | // An anonymous function generally suggests a pattern like: |
| 46 | // React.memo((props) => {...}); |
| 47 | // This kind of inner function is not used elsewhere so the side effect is okay. |
| 48 | if (!type.name && !type.displayName) { |
| 49 | Object.defineProperty(type, 'name', { |
| 50 | value: name, |
| 51 | }); |
| 52 | type.displayName = name; |
| 53 | } |
| 54 | }, |
| 55 | }); |
| 56 | } |
| 57 | return elementType; |
| 58 | } |