[Debug] Teact: Assert when virtual element keys are not unique

This commit is contained in:
Alexander Zinchuk 2022-03-05 18:06:18 +01:00
parent e679b6ae7e
commit e81475c21a

View File

@ -12,10 +12,12 @@ import {
VirtualElement, VirtualElement,
VirtualElementComponent, VirtualElementComponent,
VirtualRealElement, VirtualRealElement,
VirtualElementChildren,
} from './teact'; } from './teact';
import generateIdFor from '../../util/generateIdFor'; import generateIdFor from '../../util/generateIdFor';
import { DEBUG } from '../../config'; import { DEBUG } from '../../config';
import { addEventListener, removeEventListener } from './dom-events'; import { addEventListener, removeEventListener } from './dom-events';
import { unique } from '../../util/iteratees';
type VirtualDomHead = { type VirtualDomHead = {
children: [VirtualElement] | []; children: [VirtualElement] | [];
@ -246,6 +248,10 @@ function createNode($element: VirtualElement): Node {
function renderChildren( function renderChildren(
$current: VirtualRealElement, $new: VirtualRealElement, currentEl: HTMLElement, $current: VirtualRealElement, $new: VirtualRealElement, currentEl: HTMLElement,
) { ) {
if (DEBUG) {
DEBUG_checkKeyUniqueness($new.children);
}
if ($new.props.teactFastList) { if ($new.props.teactFastList) {
return renderFastListChildren($current, $new, currentEl); return renderFastListChildren($current, $new, currentEl);
} }
@ -482,5 +488,23 @@ function DEBUG_addToVirtualTreeSize($current: VirtualRealElement | VirtualDomHea
}); });
} }
// eslint-disable-next-line @typescript-eslint/naming-convention
function DEBUG_checkKeyUniqueness(children: VirtualElementChildren) {
const firstChild = children[0];
if (firstChild && 'props' in firstChild && firstChild.props.key !== undefined) {
const keys = children.reduce((acc: any[], child) => {
if ('props' in child && child.props.key) {
acc.push(child.props.key);
}
return acc;
}, []);
if (keys.length !== unique(keys).length) {
throw new Error('[Teact] Children keys are not unique');
}
}
}
const TeactDOM = { render }; const TeactDOM = { render };
export default TeactDOM; export default TeactDOM;