- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个使用 Svelte(带有 Astro 的 SSR)的应用,并且我正在尝试将我的数据保存到 localStorage
。
关于这个 IMO 的文档还不够,因为我似乎经常遇到砖墙。
到目前为止我已经定义了这个商店:
import { writable } from 'svelte/store'
function createCart() {
const { subscribe, set, update } = writable([]);
return {
subscribe,
update: (item) => update(value => [...value, item]),
remove: (item) => update(n => {
if(n.length > 0) n.pop() // only remove last item
return n // update the store value
}),
empty: () => set([])
};
}
export const cart = createCart()
为了保存到localStorage
(并且不会弄乱我的SSR),我已经实现了这个:
import { writable } from 'svelte/store'
function createCart() {
const defaultCartValue = []
const isClient = typeof window !== 'undefined'
const initialValue = isClient ? window.localStorage.getItem('cart') : defaultCartValue;
const { subscribe, set, update } = writable(
isClient
? window.localStorage.setItem('cart', initialValue)
: defaultCartValue
);
return {
subscribe: subscribe(value => localStorage.setItem('cart', ([
value,
...initialValue
]))),
update: (value) => isClient
? window.localStorage.setItem(
'cart',
JSON.stringify([...value, item])
)
: update(value => [...value, item]),
// TODO: fix remove items from localStorage
remove: (item => update(n => {
if(n.length > 0) n.pop()
return n
})
),
empty: () => isClient
? window.localStorage.setItem('cart', defaultCartValue)
: set(defaultCartValue)
};
}
export const cart = createCart()
我不断收到无法读取未定义的属性“取消订阅”
,然后是stop不是一个函数
。
任何人都可以帮助我理解为什么我可能会看到这两个错误吗?
最佳答案
您收到的错误:
Cannot read property 'unsubscribe' of undefined followed by stop is not a function.
那是因为 subscribe
商店的方法必须返回unsubscribe
(又名 stop
)函数。文档中并没有过多强调这一点,但它显示在方法的签名中:
subscribe: (subscription: (value: any) => void) => (() => void)
但是您自己的代码并没有做到这一点,而且,就其值(value)而言,它可能并没有真正实现您的预期:
subscribe: subscribe(value => localStorage.setItem('cart', ([
value,
...initialValue
]))),
您正在调用原始 subscribe
创建商店时立即,而不是注册新订阅者时。自原创subscribe
确实返回 unsubscribe
函数,您在尝试订阅时不会收到“不是函数”错误。但您也没有获得订阅,并且 unsubscribe
函数不返回另一个函数,这解释了您所看到的错误。
你想要的是这样的:
subscribe: subscriber => {
// do something on every new subscriber
// subscribing
const unsubscribe = originalSubscribe(value => {
// do something every time the value change FOR EVERY SUBSCRIBER
subscriber(value) // notify the subscriber of the new value
}
// custom unsubscribe function
return () => {
// do something each time a subscriber unsubscribes
unsubcribe() // unsubscribe from the original store
}
}
如果您遵循上一个片段中的注释,您应该意识到包装 subscribe
可能不是你想要坚持的localStorage
,因为通过这种方式获得的“ Hook ”适用于每个订阅者,而不是每个商店一次。
实现您想要的效果的一种方法是覆盖 set
和update
可写存储的方法,如 svelte-local-storage-store
does :
const {subscribe, set} = store
stores[key] = {
set(value: T) {
updateStorage(key, value)
set(value)
},
update(updater: Updater<T>) {
const value = updater(get(store))
updateStorage(key, value)
set(value)
},
subscribe
}
另一种极其简单且方便的模块化方法就是订阅您的商店。
// a guard because we only want this in the clients
if (!isSSR() && typeof localStorage !== 'undefined') {
originalStore.subscribe(value => {
localStorage.setItem('key', JSON.stringify(value))
})
}
这仅适用于您不介意让您的商店“始终处于事件状态”的情况;也就是说,您可能不希望对“丰富”的商店执行此操作,例如,它在获得第一个订阅者时会发出请求。
利用原始商店 subscribe
的另一种方式在避免急切订阅它的陷阱的同时,将上述逻辑包装在可读的存储中。
const createPersistedStore = initialValue => {
const internal = writable(initialValue)
const persisting = readable(initialValue, set => {
// called when the store becomes active (i.e. first subscriber arrives)
const unsubscribe = internal.subscribe(value => {
updateLocalStorage(value) // <== will see each change once
set(value)
})
return () => {
// called when the store becomes inactive (i.e. last subscriber leaves)
unsubscribe()
}
})
return {
set: internal.set,
update: internal.update,
subscribe: persisting.subscribe,
}
}
关于local-storage - 将 Svelte 存储持久保存到 localStorage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71639868/
我是 Angular 新手。使用 $localstorage(ngStorage) 是否有任何特定的原因而不是常规的 javascript localstorage 有什么区别。 谁能给我解释一下吗?
这个问题说明了一切。我意识到所有选项都可以在最新的浏览器中使用,但是语义上最好的选择是什么?为什么? 最佳答案 根据 W3C 标准,正确的是 window.localStorage,因为 localS
我想不出一个好的标题,所以希望可以。 我正在做的是创建一个离线 HTML5 webapp。 “出于某些原因”我不希望将某些文件放在缓存 list 中,而是希望将内容放在 localStorage 中。
我最近问了a question about LocalStorage .使用 JSON.parse(localStorage.item) 和 JSON.parse(localStorage['item
我最近问了a question about LocalStorage .使用 JSON.parse(localStorage.item) 和 JSON.parse(localStorage['item
我最近问过a question about LocalStorage 。使用 JSON.parse(localStorage.item) 和 JSON.parse(localStorage['item
我在将本地存储的定价添加到其他字段时遇到问题。如果我将 beforeNoonNPSlot 的价格设置为 2,但我将 matineeNPSlot 的字段留空(它应该保留分配给的任何价格)最后)。然后在我
我需要从 localStorage 对象变量中删除对象键而不从 localStorage 中删除键 let obj = localStorage; let keys = Object.keys(loc
根据我所读到的内容,我希望以下代码能够工作。 此代码是函数的一部分,该函数应该通过用下一个更高的 localStorage 变量覆盖它来删除 localStorage 变量。一旦没有更多内容可供复制,
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: JavaScript property access: dot notation vs. brackets? 我是
编写localStorage['key'] = value或localStorage.setItem('key', value)有区别吗? 我看到了this question标记为重复,但在开发人员工
我一直在做以下事情: var store = window.localStorage; store.setItem() 但现在我看到代码是这样做的: localStorage.setItem() 两者
我在 Chrome 上遇到此错误。不知道为什么会发生。任何帮助!我正在使用 Backbone.localStorage 插件和 Backbone。我在以下行中收到错误: localStorage: B
如果我尝试以下代码: var c = new Backbone.Collection(); c.localStorage = new Backbone.LocalStorage("items");
我想使用 localStorage 存储用户输入值,然后在倒计时器中使用该值。 这是用户输入数据的 HTML: Work Time
我有一个适用于 Mac 和 Linux 用户但不适用于 Windows 用户的 Chrome 扩展程序。当我进入控制台并在 localStorage 中设置一个项目时,它工作正常,但是当用户尝试使用扩
在这里浏览所有问题/答案,但找不到解决我的问题的方法。条件('localStorage' in window)返回 true但是 localStorage 的对象本身仍然是 undefined . 设
使用下面的代码,我创建一个 localstorage 变量,如果未定义,则其键为 quote = 1。然而,当最终使用相同的引号键再次调用它时,即使使用了 Number() 函数,它也会变成 11 而
我上次检查时,以下两行返回 true: null == localStorage["foo"]; null == localStorage.getItem("foo"); 将 null 替换为 und
我正在尝试在 NextJS 静态站点上使用 localStorage,但遇到 localStorage 未定义错误。 我的错误显示组件的代码是: export default function Cat
我是一名优秀的程序员,十分优秀!