Skip to content

Commit

Permalink
do not rerender reused elements in the same position or key
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Kim committed Jan 13, 2024
1 parent 357a564 commit 98f677a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/crank.ts
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@ function diffChildren<TNode, TScope, TRoot extends TNode, TResult>(
// Updating
let value: Promise<ElementValue<TNode>> | ElementValue<TNode>;
if (typeof child === "object") {
if (child.tag === Copy) {
if (child.tag === Copy || (typeof ret === "object" && ret.el === child)) {
value = getInflightValue(ret);
} else {
let oldProps: Record<string, any> | undefined;
Expand Down
40 changes: 40 additions & 0 deletions test/copy.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {suite} from "uvu";
import * as Assert from "uvu/assert";
import * as Sinon from "sinon";

import {Context, Copy, createElement, Element, Fragment} from "../src/crank.js";
import {renderer} from "../src/dom.js";
Expand Down Expand Up @@ -345,4 +346,43 @@ test("copy async generator siblings with refresh", async () => {
Assert.is(document.body.innerHTML, "<div><span>0</span><span>0</span></div>");
});

test("identical elements", () => {
const fn = Sinon.fake();
function Component() {
fn();
return <span>Hello</span>;
}
const el = <Component />;
renderer.render(el, document.body);
Assert.is(document.body.innerHTML, "<span>Hello</span>");
renderer.render(el, document.body);
Assert.is(document.body.innerHTML, "<span>Hello</span>");
Assert.is(fn.callCount, 1);
});

test("identical elements passed as children", () => {
const fn = Sinon.fake();
function Child() {
fn();
return <span>Hello</span>;
}

let ctx!: Context;
function *Parent(this: Context, {children}: {children: Element}) {

Check failure on line 371 in test/copy.tsx

View workflow job for this annotation

GitHub Actions / build

Replace `·*` with `*·`
ctx = this;
let i = 0;
for ({children} of this) {
yield <div>{children}{i}</div>;

Check failure on line 375 in test/copy.tsx

View workflow job for this annotation

GitHub Actions / build

Replace `<div>{children}{i}</div>` with `(⏎↹↹↹↹<div>⏎↹↹↹↹↹{children}⏎↹↹↹↹↹{i}⏎↹↹↹↹</div>⏎↹↹↹)`
i++;
}
}

renderer.render(<Parent><Child /></Parent>, document.body);

Check failure on line 380 in test/copy.tsx

View workflow job for this annotation

GitHub Actions / build

Replace `<Parent><Child·/></Parent>,·document.body` with `⏎↹↹<Parent>⏎↹↹↹<Child·/>⏎↹↹</Parent>,⏎↹↹document.body,⏎↹`
Assert.is(document.body.innerHTML, "<div><span>Hello</span>0</div>");
Assert.is(fn.callCount, 1);
ctx.refresh();
Assert.is(document.body.innerHTML, "<div><span>Hello</span>1</div>");
Assert.is(fn.callCount, 1);
});

test.run();

0 comments on commit 98f677a

Please sign in to comment.