From e81475c21aff9cc81978ff18ef190c961b5f1533 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Sat, 5 Mar 2022 18:06:18 +0100 Subject: [PATCH] [Debug] Teact: Assert when virtual element keys are not unique --- src/lib/teact/teact-dom.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/lib/teact/teact-dom.ts b/src/lib/teact/teact-dom.ts index 57d3e469a..c82b3c803 100644 --- a/src/lib/teact/teact-dom.ts +++ b/src/lib/teact/teact-dom.ts @@ -12,10 +12,12 @@ import { VirtualElement, VirtualElementComponent, VirtualRealElement, + VirtualElementChildren, } from './teact'; import generateIdFor from '../../util/generateIdFor'; import { DEBUG } from '../../config'; import { addEventListener, removeEventListener } from './dom-events'; +import { unique } from '../../util/iteratees'; type VirtualDomHead = { children: [VirtualElement] | []; @@ -246,6 +248,10 @@ function createNode($element: VirtualElement): Node { function renderChildren( $current: VirtualRealElement, $new: VirtualRealElement, currentEl: HTMLElement, ) { + if (DEBUG) { + DEBUG_checkKeyUniqueness($new.children); + } + if ($new.props.teactFastList) { 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 }; export default TeactDOM;