Redux / RTK:为一片创建增强器?
Redux / RTK: create enhancer for one slice?
在我的 Redux / RTK 存储中的一个切片中,要使该切片发挥作用,我需要做的就是使用 createEntityAdapter()
and export the setAll
CRUD function 创建一个实体适配器。到目前为止,如此简单 - 感谢 RTK :-)
但是,当该切片的数据传入时,我需要“增强”它(或“增强”它,如 Redux docs 所说),即添加从传入数据中派生的更多信息,因为UI(人为的例子)中格式化数据显示的示例。
我为此目的创建了一个增强器,目的是应用程序可以依赖该切片中的数据,一旦它被添加就完成了,即从一开始就包含应用程序组件所需的任何数据。 (这来自以前使用非 UI 组件的不成功方法,该组件后来监听存储更新和增强切片数据 - 这导致更新/计时问题。)
在增强器中,我拦截了感兴趣的操作并在将其添加到商店之前修改了负载(在下面的示例代码中,我只记录了操作,但你明白了......) :
export const mySliceEnhancer = (createStore) => {
return (rootReducer, preloadedState, enhancers) => {
const store = createStore(rootReducer, preloadedState, enhancers)
function newDispatch(action) {
// intercept only actions related to my slice
if (action.type === 'mySlice/setAll') {
console.debug('mySliceEnhancer > newDispatch > action.payload:\n' +
JSON.stringify(action.payload, null, 2));
}
const result = store.dispatch(action);
return result;
}
return { ...store, dispatch: newDispatch }
}
}
这有效,但全局应用于整个商店,即 dispatch
被我的自定义版本“覆盖”,以便 any 发送到商店。这让我很担心,因为例如我在 Redux Dev Extension 中丢失了 trace functionality:对于任何 dispatch
,我的增强器中的那个都会显示,无论它是否真的改变了什么。
问:有没有办法只将增强器应用于 redux 存储的一个切片?
或者 - 更笼统地问 - 我的方法是个好主意吗?
我认为这是对增强子的用途的误解。
首先,增强器总是包装整个存储对象,并且能够提供自己版本的存储方法,例如 dispatch
。
其次,“切片缩减器”是一个与商店级代码本身无关的概念。请记住,您实际上只有 一个 reducer - 您传递给 configureStore
的根 reducer。 root reducer 如何选择在内部拆分工作对 store 的其余部分无关紧要——它可能是一个巨大的函数,带有一系列 if
语句,一次处理整个状态树,或使用 combineReducers
按顶级键拆分工作。
第三,如果您正确配置了商店,使用增强器不应消除跟踪功能。根据文档,您可以使用 compose()
组合多个增强器。如果您使用的是 RTK 的 configureStore
,您可以传递一个 enhancers
数组,它将负责将它们与 DevTools 增强器正确组合在一起。
最后,由于您真正要做的只是查找特定操作并修改其内容,因此您不需要增强器。一个中间件就可以做到这一点:
const myCustomMiddleware = storeAPI => next => action => {
if (action.type === 'mySlice/setAll') {
const state = storeAPI.getState();
action.payload.someField = state.someValue;
}
return next(action);
}
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(myCustomMiddleware);
})
在我的 Redux / RTK 存储中的一个切片中,要使该切片发挥作用,我需要做的就是使用 createEntityAdapter()
and export the setAll
CRUD function 创建一个实体适配器。到目前为止,如此简单 - 感谢 RTK :-)
但是,当该切片的数据传入时,我需要“增强”它(或“增强”它,如 Redux docs 所说),即添加从传入数据中派生的更多信息,因为UI(人为的例子)中格式化数据显示的示例。
我为此目的创建了一个增强器,目的是应用程序可以依赖该切片中的数据,一旦它被添加就完成了,即从一开始就包含应用程序组件所需的任何数据。 (这来自以前使用非 UI 组件的不成功方法,该组件后来监听存储更新和增强切片数据 - 这导致更新/计时问题。)
在增强器中,我拦截了感兴趣的操作并在将其添加到商店之前修改了负载(在下面的示例代码中,我只记录了操作,但你明白了......) :
export const mySliceEnhancer = (createStore) => {
return (rootReducer, preloadedState, enhancers) => {
const store = createStore(rootReducer, preloadedState, enhancers)
function newDispatch(action) {
// intercept only actions related to my slice
if (action.type === 'mySlice/setAll') {
console.debug('mySliceEnhancer > newDispatch > action.payload:\n' +
JSON.stringify(action.payload, null, 2));
}
const result = store.dispatch(action);
return result;
}
return { ...store, dispatch: newDispatch }
}
}
这有效,但全局应用于整个商店,即 dispatch
被我的自定义版本“覆盖”,以便 any 发送到商店。这让我很担心,因为例如我在 Redux Dev Extension 中丢失了 trace functionality:对于任何 dispatch
,我的增强器中的那个都会显示,无论它是否真的改变了什么。
问:有没有办法只将增强器应用于 redux 存储的一个切片?
或者 - 更笼统地问 - 我的方法是个好主意吗?
我认为这是对增强子的用途的误解。
首先,增强器总是包装整个存储对象,并且能够提供自己版本的存储方法,例如 dispatch
。
其次,“切片缩减器”是一个与商店级代码本身无关的概念。请记住,您实际上只有 一个 reducer - 您传递给 configureStore
的根 reducer。 root reducer 如何选择在内部拆分工作对 store 的其余部分无关紧要——它可能是一个巨大的函数,带有一系列 if
语句,一次处理整个状态树,或使用 combineReducers
按顶级键拆分工作。
第三,如果您正确配置了商店,使用增强器不应消除跟踪功能。根据文档,您可以使用 compose()
组合多个增强器。如果您使用的是 RTK 的 configureStore
,您可以传递一个 enhancers
数组,它将负责将它们与 DevTools 增强器正确组合在一起。
最后,由于您真正要做的只是查找特定操作并修改其内容,因此您不需要增强器。一个中间件就可以做到这一点:
const myCustomMiddleware = storeAPI => next => action => {
if (action.type === 'mySlice/setAll') {
const state = storeAPI.getState();
action.payload.someField = state.someValue;
}
return next(action);
}
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(myCustomMiddleware);
})