Skip to content

Commit 841b641

Browse files
author
hackape
committed
fix: invalidate props in main_execution_context
1 parent 0341e0b commit 841b641

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

packages/svelte/src/compiler/compile/render_dom/invalidate.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ export function invalidate(renderer, scope, node, names, main_execution_context
3838
* @param {import('estree').Expression} [node]
3939
*/
4040
function get_invalidated(variable, node) {
41-
if (main_execution_context && !variable.subscribable && variable.name[0] !== '$') {
41+
const is_props = !!variable.export_name;
42+
if (main_execution_context && !is_props && !variable.subscribable && variable.name[0] !== '$') {
4243
return node;
4344
}
4445
return renderer_invalidate(renderer, variable.name, undefined, main_execution_context);
@@ -61,8 +62,9 @@ export function invalidate(renderer, scope, node, names, main_execution_context
6162
return x`@set_store_value(${head.name.slice(1)}, ${node}, ${head.name}, ${extra_args})`;
6263
}
6364

65+
const is_props = !!head.export_name;
6466
let invalidate;
65-
if (!main_execution_context) {
67+
if (!main_execution_context || is_props) {
6668
const pass_value =
6769
extra_args.length > 0 ||
6870
(node.type === 'AssignmentExpression' && node.left.type !== 'Identifier') ||
@@ -96,8 +98,9 @@ export function invalidate(renderer, scope, node, names, main_execution_context
9698
*/
9799
export function renderer_invalidate(renderer, name, value, main_execution_context = false) {
98100
const variable = renderer.component.var_lookup.get(name);
101+
const is_props = variable && variable.export_name && !variable.module;
99102
if (variable && variable.subscribable && (variable.reassigned || variable.export_name)) {
100-
if (main_execution_context) {
103+
if (main_execution_context && !is_props) {
101104
return x`${`$$subscribe_${name}`}(${value || name})`;
102105
} else {
103106
const member = renderer.context_lookup.get(name);
@@ -124,6 +127,9 @@ export function renderer_invalidate(renderer, name, value, main_execution_contex
124127
const member = renderer.context_lookup.get(name);
125128
return x`$$invalidate(${member.index}, ${value})`;
126129
}
130+
} else if (main_execution_context && is_props) {
131+
const member = renderer.context_lookup.get(name);
132+
return x`$$invalidate(${member.index}, ${name})`;
127133
}
128134
if (main_execution_context) return;
129135
// if this is a reactive declaration, invalidate dependencies recursively

packages/svelte/src/runtime/internal/Component.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ export function bind(component, name, callback) {
2424
const i = component.$$.props[name];
2525
if (i !== undefined) {
2626
let dirty = false;
27-
if (component.$$.bound[i]) dirty = true;
27+
// special dirty flag for bind
28+
if (component.$$.bound[i] === null) dirty = true;
2829
component.$$.bound[i] = callback;
2930
// first binding call, if child value is not yet dirty, skip to prevent unnecessary backflow
3031
callback(component.$$.ctx[i], /** skip_binding */ !dirty);
@@ -127,10 +128,13 @@ export function init(
127128
$$.ctx = instance
128129
? instance(component, options.props || {}, (i, ret, ...rest) => {
129130
const value = rest.length ? rest[0] : ret;
131+
// `$$.bound[i] = null` as a special dirty flag to prevent unnecessary backflow, consumed in bind()
132+
// only set at init phase during `instance()` call, and 1st `$$.update()` call before `ready`
133+
if (!$$.ctx) $$.bound[i] = null;
130134
if ($$.ctx && not_equal($$.ctx[i], ($$.ctx[i] = value))) {
131-
if (!$$.skip_bound && is_function($$.bound[i])) $$.bound[i](value);
135+
if (!$$.skip_bound && $$.bound[i]) $$.bound[i](value);
132136
if (ready) make_dirty(component, i);
133-
else $$.bound[i] = true; // dirty flag consumed in bind()
137+
else $$.bound[i] = null;
134138
}
135139
return ret;
136140
})

0 commit comments

Comments
 (0)