* Warns if there is a duplicate or missing key
(
returnFiber: Fiber,
workInProgress: Fiber,
child: mixed,
knownKeys: Set<string> | null,
)
| 1067 | * Warns if there is a duplicate or missing key |
| 1068 | */ |
| 1069 | function warnOnInvalidKey( |
| 1070 | returnFiber: Fiber, |
| 1071 | workInProgress: Fiber, |
| 1072 | child: mixed, |
| 1073 | knownKeys: Set<string> | null, |
| 1074 | ): Set<string> | null { |
| 1075 | if (__DEV__) { |
| 1076 | if (typeof child !== 'object' || child === null) { |
| 1077 | return knownKeys; |
| 1078 | } |
| 1079 | switch (child.$$typeof) { |
| 1080 | case REACT_ELEMENT_TYPE: |
| 1081 | case REACT_PORTAL_TYPE: |
| 1082 | warnForMissingKey(returnFiber, workInProgress, child); |
| 1083 | const key = child.key; |
| 1084 | if (typeof key !== 'string') { |
| 1085 | break; |
| 1086 | } |
| 1087 | if (knownKeys === null) { |
| 1088 | knownKeys = new Set(); |
| 1089 | knownKeys.add(key); |
| 1090 | break; |
| 1091 | } |
| 1092 | if (!knownKeys.has(key)) { |
| 1093 | knownKeys.add(key); |
| 1094 | break; |
| 1095 | } |
| 1096 | runWithFiberInDEV(workInProgress, () => { |
| 1097 | console.error( |
| 1098 | 'Encountered two children with the same key, `%s`. ' + |
| 1099 | 'Keys should be unique so that components maintain their identity ' + |
| 1100 | 'across updates. Non-unique keys may cause children to be ' + |
| 1101 | 'duplicated and/or omitted — the behavior is unsupported and ' + |
| 1102 | 'could change in a future version.', |
| 1103 | key, |
| 1104 | ); |
| 1105 | }); |
| 1106 | break; |
| 1107 | case REACT_LAZY_TYPE: { |
| 1108 | const resolvedChild = resolveLazy((child: any)); |
| 1109 | warnOnInvalidKey( |
| 1110 | returnFiber, |
| 1111 | workInProgress, |
| 1112 | resolvedChild, |
| 1113 | knownKeys, |
| 1114 | ); |
| 1115 | break; |
| 1116 | } |
| 1117 | default: |
| 1118 | break; |
| 1119 | } |
| 1120 | } |
| 1121 | return knownKeys; |
| 1122 | } |
| 1123 | |
| 1124 | function reconcileChildrenArray( |
| 1125 | returnFiber: Fiber, |
no test coverage detected