Closed
Description
Version
vue-next
Reproduction link
HowGraceU/vue-next@de01ffb#diff-d1223243b498cec786e7864834bc0acfL158
Steps to reproduce
it('should observe iteration', () => {
let dummy
const list = reactive(['Hello'])
const fn = jest.fn(() => (dummy = list.join(' ')));
effect(fn)
expect(fn).toHaveBeenCalledTimes(1) // normal
expect(dummy).toBe('Hello')
list.push('World!')
expect(dummy).toBe('Hello World!')
expect(fn).toHaveBeenCalledTimes(2) // normal
list.shift()
expect(dummy).toBe('World!')
expect(fn).toHaveBeenCalledTimes(5) // It depends on list.length
})
What is expected?
effect should only be called once
What is actually happening?
effect is called more than once
this is due to shift will trigger set function more than once
a = new Proxy([1,2,3,4,5,6,7,8,9,10], {
set(target, key, value, p) {
const oldValue = target[key];
console.log(`key:${key} oldValue: ${oldValue} v:${value}`);
return Reflect.set(target, key, value, p);
}
});
a.shift();
/*
* log
* key:0 oldValue: 1 v:2
* key:1 oldValue: 2 v:3
* key:2 oldValue: 3 v:4
* key:3 oldValue: 4 v:5
* key:4 oldValue: 5 v:6
* key:5 oldValue: 6 v:7
* key:6 oldValue: 7 v:8
* key:7 oldValue: 8 v:9
* key:8 oldValue: 9 v:10
* key:length oldValue: 10 v:9
*/
should cache effect funtion, like Watch Object in Vue 2, and trigger it nexttick?
Metadata
Metadata
Assignees
Labels
No labels