From fb7ac44a2fd82eb54bf1425e3e0db3391f3e7b89 Mon Sep 17 00:00:00 2001 From: Ranjan Shrestha Date: Thu, 8 Feb 2024 18:01:42 +0545 Subject: [PATCH] Cleanup the existing child node before repositioning to avoid memory leak (#2206) Fixes #2183, During re-renders when the child nodes where being rearranged, the new nodes were inserted without removing the existing ones. --------- Co-authored-by: William Candillon --- package/cpp/rnskia/dom/base/JsiDomNode.h | 16 ++++++++++++++++ package/src/dom/nodes/Node.ts | 1 + 2 files changed, 17 insertions(+) diff --git a/package/cpp/rnskia/dom/base/JsiDomNode.h b/package/cpp/rnskia/dom/base/JsiDomNode.h index 3d47ec57cf..50b1cab644 100644 --- a/package/cpp/rnskia/dom/base/JsiDomNode.h +++ b/package/cpp/rnskia/dom/base/JsiDomNode.h @@ -370,6 +370,14 @@ class JsiDomNode : public JsiHostObject, enqueAsynOperation([child, weakSelf = weak_from_this()]() { auto self = weakSelf.lock(); if (self) { + // Remove the existing instance of the child, before adding it to the + // end of the list + auto existingPosition = + std::find(self->_children.begin(), self->_children.end(), child); + if (existingPosition != self->_children.end()) { + self->_children.erase(existingPosition); + } + self->_children.push_back(child); child->setParent(self.get()); } @@ -390,6 +398,14 @@ class JsiDomNode : public JsiHostObject, enqueAsynOperation([child, before, weakSelf = weak_from_this()]() { auto self = weakSelf.lock(); if (self) { + // Remove the existing instance of the child + // before adding it in the new position + auto existingPosition = + std::find(self->_children.begin(), self->_children.end(), child); + if (existingPosition != self->_children.end()) { + self->_children.erase(existingPosition); + } + auto position = std::find(self->_children.begin(), self->_children.end(), before); self->_children.insert(position, child); diff --git a/package/src/dom/nodes/Node.ts b/package/src/dom/nodes/Node.ts index 2d60647e8e..8faff97b72 100644 --- a/package/src/dom/nodes/Node.ts +++ b/package/src/dom/nodes/Node.ts @@ -38,6 +38,7 @@ export abstract class JsiNode

implements Node

{ } addChild(child: Node) { + this.removeChild(child); this._children.push(child as JsiNode); }