Merge pull request #1366 from sveltejs/gh-1353

prevent stale state in component event handlers
pull/1370/head
Rich Harris 7 years ago committed by GitHub
commit 4f86820cf0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,6 +10,7 @@ import mungeAttribute from './shared/mungeAttribute';
import Node from './shared/Node';
import Block from '../dom/Block';
import Attribute from './Attribute';
import usesThisOrArguments from '../../validate/js/utils/usesThisOrArguments';
export default class Component extends Node {
type: 'Component';
@ -494,8 +495,11 @@ function mungeEventHandler(generator: DomGenerator, node: Node, handler: Node, b
);
}
let usesState = false;
handler.expression.arguments.forEach((arg: Node) => {
const { contexts } = block.contextualise(arg, null, true);
if (contexts.has('state')) usesState = true;
contexts.forEach(context => {
allContexts.add(context);
@ -503,11 +507,12 @@ function mungeEventHandler(generator: DomGenerator, node: Node, handler: Node, b
});
body = deindent`
${usesState && `const state = #component.get();`}
[${handler.expression.start}-${handler.expression.end}];
`;
} else {
body = deindent`
${block.alias('component')}.fire('${handler.name}', event);
#component.fire('${handler.name}', event);
`;
}

@ -0,0 +1,30 @@
export default {
data: {
value: 1,
},
test(assert, component, target, window) {
const buttons = target.querySelectorAll('button');
const click = new window.MouseEvent('click');
const events = [];
component.on('value', event => {
events.push(event);
});
buttons[0].dispatchEvent(click);
buttons[1].dispatchEvent(click);
component.set({ value: 2 });
buttons[0].dispatchEvent(click);
buttons[1].dispatchEvent(click);
assert.deepEqual(events, [
{ value: 1 },
{ value: 1 },
{ value: 2 },
{ value: 2 }
]);
},
};

@ -0,0 +1,20 @@
<Button on:click="handleClick()">one</Button>
<Button on:click="fire('value', {value})">two</Button>
<script>
import Button from './Button.html';
export default {
components: {
Button
},
methods: {
handleClick() {
const { value } = this.get();
this.fire('value', { value });
}
}
}
</script>
Loading…
Cancel
Save