我不明白如何在组件中使用可写存储并且仍然让 DOM 对状态的变化做出反应。
我想更改存储状态对象键并检索其最新值,然后将其用于组件中。
商店确实更新正确。唯一的问题是在存储状态更改时更新 DOM。
状态和存储类型
import { Writable, writable } from 'svelte/store';
export interface Words { [key: string]: boolean };
export interface SelectedWordsStore extends Writable<Words> {
setWord: (key: string, state: boolean) => void;
isWordSelected: (key: string) => boolean;
reset: () => void;
}
店铺
function createSelectedWordsStore(): SelectedWordsStore {
const state: Words = {};
const store: Writable<Words> = writable(state);
return {
...store,
setWord: (key: string, isSelected: boolean) => store.update((words) => {
words[key] = isSelected;
return words;
}),
isWordSelected: (key: string) => {
return state[key] ?? false;
},
reset: () => store.set({}),
}
}
export const selectedWordsStore = createSelectedWordsStore();
用法
它被用在一个苗条的组件和一个 TS 帮助文件中
<script lang="ts">
import Word from './components/Word.svelte';
import { words, getWordKey } from './helpers/words';
import type { IndexProps } from './helpers/words';
import { isBingo } from './helpers/bingo';
import { selectedWordsStore } from './selected-words.store';
const onWordClick = ({ currentTarget }: TypedMouseEvent<HTMLDivElement>): void => {
const parent = currentTarget.parentElement;
const columnId = parent.dataset.columnId;
const wordId = currentTarget.dataset.id;
const key = getWordKey({ columnId, wordId })
selectedWordsStore.setWord(
key,
!selectedWordsStore.isWordSelected(key),
)
isBingo(...); // <--- store used here as well
}
function isWordSelected(options: IndexProps): boolean {
return selectedWordsStore.isWordSelected(getWordKey(options));
}
</script>
<div class="container" data-testid="container">
{#each words as wordGroup, columnId}
<div data-column-id={columnId}>
{#each wordGroup as word, wordId}
<Word
on:click={onWordClick}
name={word}
isSelected={isWordSelected({ columnId, wordId })} <!-- USAGE -->
wordId={wordId}
/>
{/each}
</div>
{/each}
</div>
期望的结果
我希望在调用onWordClick
DOM 后重新检查isWordSelected
并将最新的布尔值Word
从商店传递给组件
更新
我找到了一个可行的解决方案
isSelected={$selectedWordsStore && isWordSelected({ columnId, wordId })}
但是,不确定这是最好的方法。有什么建议么?
更新 2
现在 store 上的 reset 回调会阻止 DOM 上的反应。也就是说,在按下重置后,DOM 或助手中不会反映任何状态更改。