Skip to content
This repository was archived by the owner on Mar 1, 2023. It is now read-only.

Commit cff84bf

Browse files
committed
fix(3in2): smarter diff check for component values
Svelte will tell us that it changed, even if it's a reference to the exact same object. To avoid re-creating the svelte3 component constantly the wrapper needs to do a more specific diff before re-instantiating the svelte3 component.
1 parent 68ade79 commit cff84bf

File tree

2 files changed

+42
-17
lines changed

2 files changed

+42
-17
lines changed

3in2/component.html

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@
4646

4747
if(component) {
4848
this.instantiate();
49-
}
49+
}
5050

51-
this.on("state", ({ changed, current }) => {
52-
if(changed.component) {
51+
this.on("state", ({ changed, current, previous }) => {
52+
// Second check is because svelte's diffing is pretty basic by default, so
53+
// we need to be smarter about allowing inntances to persist
54+
if(changed.component && (current.component !== previous.component)) {
5355
return this.instantiate();
5456
}
55-
57+
5658
if(this.instance) {
5759
return this.instance.$set(current);
5860
}

3in2/tests/component.test.js

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ describe("3in2 component wrapper", () => {
66
const Wrapper = require("../component.html");
77
const { default : ComponentA } = require("./specimens/component-a.svelte");
88
const { default : ComponentB } = require("./specimens/component-b.svelte");
9-
9+
1010
let root;
1111

1212
beforeEach(() => {
@@ -47,7 +47,7 @@ describe("3in2 component wrapper", () => {
4747

4848
expect(wrapper.instance).toBeNull();
4949
});
50-
50+
5151
it("should render a svelte3 component w/ props", async () => {
5252
new Wrapper({
5353
target : root,
@@ -61,7 +61,7 @@ describe("3in2 component wrapper", () => {
6161

6262
expect(root.innerHTML).toMatchSnapshot();
6363
});
64-
64+
6565
it("should update the svelte3 component when props change", async () => {
6666
const wrapper = new Wrapper({
6767
target : root,
@@ -74,16 +74,39 @@ describe("3in2 component wrapper", () => {
7474
});
7575

7676
expect(root.innerHTML).toMatchSnapshot();
77-
77+
7878
wrapper.set({
7979
a : "A2",
8080
});
8181

8282
await wait();
83-
83+
8484
expect(root.innerHTML).toMatchSnapshot();
8585
});
86-
86+
87+
it("shouldn't recreate the svelte3 component when props change", async () => {
88+
const wrapper = new Wrapper({
89+
target : root,
90+
91+
data : {
92+
component : ComponentA,
93+
94+
a : "A",
95+
},
96+
});
97+
98+
const child = wrapper.instance;
99+
100+
wrapper.set({
101+
component : ComponentA,
102+
a : "A2",
103+
});
104+
105+
await wait();
106+
107+
expect(child).toBe(wrapper.instance);
108+
});
109+
87110
it("should support swapping out the svelte3 component", async () => {
88111
const wrapper = new Wrapper({
89112
target : root,
@@ -96,36 +119,36 @@ describe("3in2 component wrapper", () => {
96119
});
97120

98121
expect(root.innerHTML).toMatchSnapshot();
99-
122+
100123
wrapper.set({
101124
component : ComponentB,
102125
});
103126

104127
await wait();
105-
128+
106129
expect(root.innerHTML).toMatchSnapshot();
107130
});
108-
131+
109132
it("should support creation without a component", async () => {
110133
const wrapper = new Wrapper({
111134
target : root,
112135
});
113136

114137
expect(root.innerHTML).toMatchSnapshot();
115-
138+
116139
wrapper.set({
117140
component : ComponentB,
118141
});
119142

120143
await wait();
121-
144+
122145
expect(root.innerHTML).toMatchSnapshot();
123146
});
124-
147+
125148
it("should set attributes on the wrapper element it creates", async () => {
126149
new Wrapper({
127150
target : root,
128-
151+
129152
data : {
130153
component : ComponentA,
131154

0 commit comments

Comments
 (0)