Mr.*_*ody 11 typescript reactjs react-redux redux-toolkit
我正在使用 redux-toolkit,并且尝试在每次更新商店后将状态保存到本地存储,而不使用任何第三方库。原因是 redux-persist 不再更新,我不知道有什么好的替代方案。经过大量时间寻找解决方案后,我想出了使用createListenerMiddleware.
import { configureStore, createListenerMiddleware } from "@reduxjs/toolkit";
import counterSlice, { decrement, increment } from "../Slices/counterSlice";
const listenerMiddleware = createListenerMiddleware()
listenerMiddleware.startListening({
actionCreator: increment,
effect: () => (
localStorage.setItem('count', JSON.stringify(store.getState().counter))
)
})
const listenerMiddleware2 = createListenerMiddleware()
listenerMiddleware.startListening({
actionCreator: decrement,
effect: () => (
localStorage.setItem('count', JSON.stringify(store.getState().counter))
)
})
const counterState = JSON.parse(localStorage.getItem('count') || "null")
export const store = configureStore({
preloadedState: {
counter: counterState === null ? { value: 0 } : counterState
},
reducer: {
counter: counterSlice
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(listenerMiddleware2.middleware, listenerMiddleware.middleware)
})
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我这是否是一个好主意,如果不是,是否还有其他正确的方法。
Lin*_*ste 16
您的方向是正确的,但有一些变化:
您应该从回调的参数访问该函数,而不是store直接使用变量来调用。getState()getState()effect
effect: (action: Action, listenerApi: ListenerApi) => void | Promise<void>
Run Code Online (Sandbox Code Playgroud)
您的effect函数使用两个参数调用:action触发效果的 和listenerApi对象,它使您可以访问getState()和许多其他实用程序。
侦听器中间件不知道存储的 TypeScript 类型,因此您需要以某种方式让它知道。实现此目的的一种方法是as在listenerApi.getState()调用时使用内联断言。
listenerMiddleware.startListening({
actionCreator: increment,
effect: (action, listenerApi) =>
localStorage.setItem("count", JSON.stringify((listenerApi.getState() as RootState).counter))
});
Run Code Online (Sandbox Code Playgroud)
您还可以按照文档的TypeScript 用法TypedStartListening部分并使用实用程序类型。
您不需要多个侦听器中间件实例,因为您可以将多个侦听器附加到同一中间件。startListening对同一变量进行多次简单调用listenerMiddleware。
然而,在这种情况下,startListening您只需要一个电话即可!您的两个案例已经有相同的effect回调。但我们需要能够匹配increment和decrement行动。侦听器可以通过几种不同的方式来检测匹配的操作。actionCreator我们将使用该属性,而不是只能匹配单个操作的using matcher。isAnyOf我们在实用程序的帮助下创建了一个匹配器函数。
我们最终的中间件如下所示:
import { createListenerMiddleware, isAnyOf } from "@reduxjs/toolkit";
import { decrement, increment } from "./slice";
import type { RootState } from "./index";
export const listenerMiddleware = createListenerMiddleware();
listenerMiddleware.startListening({
matcher: isAnyOf(increment, decrement),
effect: (action, listenerApi) =>
localStorage.setItem(
"count",
JSON.stringify((listenerApi.getState() as RootState).counter)
)
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5351 次 |
| 最近记录: |