only call onchange callbacks once per array mutation

pull/15073/head
Rich Harris 2 years ago
parent e42c7cd567
commit 54a17b57a0

@ -9,13 +9,15 @@ import {
object_prototype
} from '../shared/utils.js';
import { check_ownership, widen_ownership } from './dev/ownership.js';
import { source, set, state } from './reactivity/sources.js';
import { source, set, state, set_call_onchange } from './reactivity/sources.js';
import { STATE_SYMBOL, STATE_SYMBOL_METADATA } from './constants.js';
import { UNINITIALIZED } from '../../constants.js';
import * as e from './errors.js';
import { get_stack } from './dev/tracing.js';
import { tracing_mode_flag } from '../flags/index.js';
const array_methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'reverse', 'sort'];
/**
* @template T
* @param {T} value
@ -168,7 +170,22 @@ export function proxy(value, options, parent = null, prev) {
return v === UNINITIALIZED ? undefined : v;
}
return Reflect.get(target, prop, receiver);
const value = Reflect.get(target, prop, receiver);
if (is_proxied_array && array_methods.includes(/** @type {string} */ (prop))) {
// @ts-expect-error
return (...args) => {
set_call_onchange(false);
const result = value.apply(receiver, args);
set_call_onchange(true);
options?.onchange?.();
return result;
};
}
return value;
},
getOwnPropertyDescriptor(target, prop) {

@ -45,6 +45,13 @@ export function set_inspect_effects(v) {
inspect_effects = v;
}
let call_onchange = true;
/** @param {boolean} v */
export function set_call_onchange(v) {
call_onchange = v;
}
/**
* @template V
* @param {V} v
@ -191,7 +198,10 @@ export function internal_set(source, value) {
var old_value = source.v;
source.v = value;
source.wv = increment_write_version();
untrack(() => source.o?.onchange?.());
if (call_onchange) {
untrack(() => source.o?.onchange?.());
}
if (DEV && tracing_mode_flag) {
source.updated = get_stack('UpdatedAt');

Loading…
Cancel
Save