我正在使用useReducer钩子来保存一些全局状态。因为我想在关闭浏览器时保存一些设置,所以将这些设置保存到本地存储中。
目前,我使用分派来保存设置,并使用单独的功能将其保存到本地存储中,但是如果在分派后自动保存设置,那就很好了。 (有时我会忘记保存到本地存储,而状态/本地存储之间会有区别)
从本地存储读取状态不是问题。为此,我在useReducer挂钩中使用了initialState参数。
我认为答案是不这样做,但是替代品是什么? (不使用redux)
答案 0 :(得分:1)
我认为让服务负责将数据存储到localStorage以及将其存储到localStorage是明智的。因此,您可能想使用get和set函数创建服务。您可以从redux中的效果调用服务。
我认为,减速器在那里可以改变状态。
您还可以使用rxjs等待reducer更新您的状态,然后使用您的服务获取该状态并将其保存到localStorage。
顺便说一句,根据您的需要,我没有发现没有任何理由不应该将数据存储在localStorage中,只要您记住(使用redux时)记住redux状态是您唯一的真理。以我最诚实的看法,将数据存储在某个位置以在初始化时恢复该状态是一个好方法。
以下是使用ngrx的示例:
@Effect()
myAction$: Observable<Action> = this.actions$.pipe(
ofType<MyAction>(actions.myAction),
debounceTime(300),
switchMap((action) =>
this.service.post(action.dto).pipe(
map((response: SomeDto) => {
// This updates the state using a reducer
return new CreateShortenedLinkSuccess(response);
}),
tap((value) => {
// Here, you can use the value param, to save
// changes to localStorage
this.router.navigate([`/mgmt/link/${value.dto.id}`]);
}),
catchError((response: HttpErrorResponse) => {
// Do scary stuff
})
)
)
);
答案 1 :(得分:1)
我发现@Zaid Crouch很棒,但是它不能处理来自不同窗口(选项卡/ iframe /弹出窗口)的本地存储更新。
REPLACE
答案 2 :(得分:0)
我只是在做类似的事情,并且想尝试使用可以代替useReducer的自定义钩子来实现它。出现了以下粗略的钩子(我确实添加了一个额外的参数,以便可以指定数据存储在其下的键):
import { useRef, useReducer } from 'react'
function useLocallyPersistedReducer(reducer, defaultState, storageKey) {
const isLoading = useRef(true)
if (isLoading.current) {
try {
const persisted = JSON.parse(localStorage.getItem(storageKey))
defaultState = persisted
} catch (e) {
console.warn(`Failed to load state '${storageKey}' from localStorage; using default state instead`)
}
isLoading.current = false
}
const [ state, dispatch ] = useReducer(reducer, defaultState)
try {
localStorage.setItem(storageKey, JSON.stringify(state))
} catch (e) {
console.warn(`Failed to store updated state '${storageKey}'`)
}
return [ state, dispatch ]
}
作为一项艰巨的工作,它可以工作,但是我可能错过了一些细微差别。希望能使您对如何实现这一想法有所了解!