Skip to content

Commit

Permalink
Fix: beforeUpdate called twice with bound reference
Browse files Browse the repository at this point in the history
  • Loading branch information
RaiVaibhav committed Oct 19, 2021
1 parent 883c47b commit 7891d4b
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 6 deletions.
19 changes: 13 additions & 6 deletions src/runtime/internal/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export function add_flush_callback(fn) {

let flushing = false;
const seen_callbacks = new Set();
let dirty_binding_component_map = new Map();

export function flush() {
if (flushing) return;
flushing = true;
Expand All @@ -43,14 +45,19 @@ export function flush() {
for (let i = 0; i < dirty_components.length; i += 1) {
const component = dirty_components[i];
set_current_component(component);
update(component.$$);
const is_dirty_from_binding = dirty_binding_component_map.has(component.constructor.name);
update(component.$$, is_dirty_from_binding);
}
dirty_binding_component_map = new Map();
set_current_component(null);

dirty_components.length = 0;

while (binding_callbacks.length) binding_callbacks.pop()();

while (binding_callbacks.length) {
binding_callbacks.pop()();
}
dirty_components.forEach((i) =>
dirty_binding_component_map.set(i.constructor.name, i));
// then, once components are updated, call
// afterUpdate functions. This may cause
// subsequent updates...
Expand All @@ -77,14 +84,14 @@ export function flush() {
seen_callbacks.clear();
}

function update($$) {
function update($$, is_dirty_from_binding) {
if ($$.fragment !== null) {
$$.update();
run_all($$.before_update);
if (!is_dirty_from_binding) run_all($$.before_update);
const dirty = $$.dirty;
$$.dirty = [-1];
$$.fragment && $$.fragment.p($$.ctx, dirty);

// if (!is_dirty_from_binding) run_all($$.after_update);
$$.after_update.forEach(add_render_callback);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script>
import { onMount, beforeUpdate, afterUpdate } from 'svelte';
import order from './order.js';
let i;
export let index;
export let id;
export let name;
function logRender () {
order.push(`${index}: render`);
return index;
}
beforeUpdate(() => {
order.push(`${index}: beforeUpdate`);
});
afterUpdate(() => {
order.push(`${index}: afterUpdate`);
});
onMount(() => {
order.push(`${index}: onMount`);
});
</script>

<li bind:this={i}>
{logRender()}
</li>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import order from './order.js';

export default {
skip_if_ssr: true,
before_test() {
order.length = 0;
},
test({ assert, compileOptions }) {
if (compileOptions.hydratable) {
assert.deepEqual(order, [
'0: beforeUpdate',
'0: render',
'1: beforeUpdate',
'1: render',
'2: beforeUpdate',
'2: render',
'3: beforeUpdate',
'3: render',
'1: onMount',
'1: afterUpdate',
'2: onMount',
'2: afterUpdate',
'3: onMount',
'3: afterUpdate',
'0: onMount',
'0: afterUpdate'
]);
} else {
assert.deepEqual(order, [
'0: beforeUpdate',
'0: render',
'1: beforeUpdate',
'2: beforeUpdate',
'3: beforeUpdate',
'1: render',
'2: render',
'3: render',
'1: onMount',
'1: afterUpdate',
'2: onMount',
'2: afterUpdate',
'3: onMount',
'3: afterUpdate',
'0: onMount',
'0: afterUpdate'
]);
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<script>
import { onMount, beforeUpdate, afterUpdate } from 'svelte';
import order from './order.js';
import Item from './Item.svelte';
const parentIndex = 0;
let ul;
let ulW;
function logRender () {
order.push(`${parentIndex}: render`);
return parentIndex;
}
beforeUpdate(() => {
order.push(`${parentIndex}: beforeUpdate`);
});
afterUpdate(() => {
order.push(`${parentIndex}: afterUpdate`);
});
onMount(() => {
order.push(`${parentIndex}: onMount`);
})
</script>

{logRender()}
<ul bind:this={ul} bind:clientWidth={ulW}>
{#each [1,2,3] as index}
<Item {index} />
{/each}
</ul>


Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default [];

0 comments on commit 7891d4b

Please sign in to comment.