#javascript #svelte #svelte-3 #svelte-component #svelte-store
Вопрос:
Вот РЕПЛ: https://svelte.dev/repl/56770fec88af4b76bdc8ea962178854e?version=3.42.1
Вот код:
Приложение.стройная:
<script>
import {editableStore} from "./store";
let name = "John"
$: player = editableStore(name);
</script>
<h1>Hello {$player.name}!</h1>
<button on:click={() => name = (name === "Bob" ? "Jerry" : "Bob")}>
Change name
</button>
<h2>Log:</h2>
{#each $player.log as log}
<li>{log}</li>
{/each}
store.js:
import {writable} from "svelte/store";
const defaultStore = {
name: "Bob",
age: 18,
log: []
};
export const editableStore = (name) => {
console.log("Recreated with name:", name);
const {subscribe, update} = writable({...defaultStore}, () => () => clearInterval);
if (name) {
update(s => ({...s, name}));
}
const clearInterval = setInterval(() => {
update(s => ({...s, log: [...s.log, new Date()]}))
}, 1000)
return { subscribe };
};
Как вы можете видеть, если вы нажмете «Изменить имя», магазин будет воссоздан заново.
Это то, чего мне нужно избегать.
Но как?
Комментарии:
1. Вы должны следовать руководству по магазину Svelte: svelte.dev/учебник/доступные для записи-магазины
Ответ №1:
Вместо того, чтобы воссоздавать магазин каждый раз name
, когда он меняется, создайте его только один раз и установите $player.name
время name
изменения.
<script>
import {editableStore} from "./store";
let name = "John";
let player = editableStore(name);
$: $player.name = name;
</script>
Для этого потребуется обновить метод хранилища, чтобы вернуть set
функцию.
export const editableStore = (name) => {
console.log("Recreated with name:", name);
// also destructure set here
const {subscribe, update, set} = writable({...defaultStore}, () => () => clearInterval);
if (name) {
update(s => ({...s, name}));
}
const clearInterval = setInterval(() => {
update(s => ({...s, log: [...s.log, new Date()]}))
}, 1000)
// also return set here
return { subscribe, set };
};
Ответ №2:
Попробуйте создать экземпляр вашего хранилища как можно быстрее, как в ./store.js
файле, а затем используйте метод set
или update
вместо того, чтобы создавать его непосредственно в компоненте:
// store.js
import {writable} from "svelte/store";
const defaultStore = {
name: "Bob",
age: 18,
log: []
};
export const createEditableStore = () => {
const {subscribe, update, set} = writable({...defaultStore}, () => () => clearInterval);
const clearInterval = setInterval(() => {
update(s => ({...s, log: [...s.log, new Date()]}))
}, 1000)
return { subscribe, set, update };
};
export const player = createEditableStore()
<!-- App.svelte -->
<script>
import { player } from "./store";
let name = "John"
$: player.update(p => ({ ...p, name }))
</script>
<h1>Hello {$player.name}!</h1>
<button on:click={() => name = (name === "Bob" ? "Jerry" : "Bob")}>
Change name
</button>
<h2>Log:</h2>
{#each $player.log as log}
<li>{log}</li>
{/each}
Взгляните на РЕПЛ.