Fix rare issue which could occur when enriching component props twice before an initial render has taken place
This commit is contained in:
parent
611dc0ab48
commit
7656887c1a
|
@ -276,27 +276,29 @@
|
||||||
// reactive statements as much as possible.
|
// reactive statements as much as possible.
|
||||||
const cacheSettings = (enriched, nested, conditional) => {
|
const cacheSettings = (enriched, nested, conditional) => {
|
||||||
const allSettings = { ...enriched, ...nested, ...conditional }
|
const allSettings = { ...enriched, ...nested, ...conditional }
|
||||||
if (!cachedSettings) {
|
const mounted = ref?.$$set != null
|
||||||
|
if (!cachedSettings || !mounted) {
|
||||||
cachedSettings = { ...allSettings }
|
cachedSettings = { ...allSettings }
|
||||||
initialSettings = cachedSettings
|
initialSettings = cachedSettings
|
||||||
} else {
|
} else {
|
||||||
Object.keys(allSettings).forEach(key => {
|
Object.keys(allSettings).forEach(key => {
|
||||||
const same = propsAreSame(allSettings[key], cachedSettings[key])
|
const same = propsAreSame(allSettings[key], cachedSettings[key])
|
||||||
if (!same) {
|
if (!same) {
|
||||||
|
// Updated cachedSettings (which is assigned by reference to
|
||||||
|
// initialSettings) so that if we remount the component then the
|
||||||
|
// initial props are up to date. By setting it this way rather than
|
||||||
|
// setting it on initialSettings directly, we avoid a double render.
|
||||||
cachedSettings[key] = allSettings[key]
|
cachedSettings[key] = allSettings[key]
|
||||||
assignSetting(key, allSettings[key])
|
|
||||||
|
// Programmatically set the prop to avoid svelte reactive statements
|
||||||
|
// firing inside components. This circumvents the problems caused by
|
||||||
|
// spreading a props object.
|
||||||
|
ref.$$set({ [key]: allSettings[key] })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assigns a certain setting to this component.
|
|
||||||
// We manually use the svelte $set function to avoid triggering additional
|
|
||||||
// reactive statements.
|
|
||||||
const assignSetting = (key, value) => {
|
|
||||||
ref?.$$set?.({ [key]: value })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a key used to determine when components need to fully remount.
|
// Generates a key used to determine when components need to fully remount.
|
||||||
// Currently only toggling editing requires remounting.
|
// Currently only toggling editing requires remounting.
|
||||||
const getRenderKey = (id, editing) => {
|
const getRenderKey = (id, editing) => {
|
||||||
|
@ -305,7 +307,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#key renderKey}
|
{#key renderKey}
|
||||||
{#if constructor && cachedSettings && (visible || inSelectedPath)}
|
{#if constructor && initialSettings && (visible || inSelectedPath)}
|
||||||
<!-- The ID is used as a class because getElementsByClassName is O(1) -->
|
<!-- The ID is used as a class because getElementsByClassName is O(1) -->
|
||||||
<!-- and the performance matters for the selection indicators -->
|
<!-- and the performance matters for the selection indicators -->
|
||||||
<div
|
<div
|
||||||
|
|
Loading…
Reference in New Issue