[英]@ngrx/entity `Cannot read property 'ids' of undefined` when using together with @ngrx/store? already accounting for custom ids when defining adapter
我已經查看了其他 2 篇關於此的文章,一篇包含較大的 state 的文章不適用,而另一篇注冊了多個 forFeature - 我已經對此進行了一些測試,即使我在之前或之后導入它forRoot(reducers) 在我的 app.module 中,它沒有區別。
我確定我在配置中遺漏了一些明顯的東西。
我的配置:
export const orderAdapter: EntityAdapter<IOrder> = createEntityAdapter<IOrder>({
selectId: (order: IOrder) => order._id
});
export interface AllOrdersState extends EntityState<IOrder> {}
export const initialState: AllOrdersState = orderAdapter.getInitialState({
ids: [],
entities: {}
});
export const OrdersState = createFeatureSelector<AllOrdersState>('orders');
export const {
selectIds,
selectEntities,
selectAll,
selectTotal
} = orderAdapter.getSelectors(OrdersState);
我的實際減速器:
export function ordersReducer(
state: AllOrdersState = initialState,
action: actions.OrdersActions
) {
case actions.CREATE_MANY: {
console.log(action.orders);
return orderAdapter.addMany(action.orders, state);
}
}
我在我的 Order.Module 中注冊為:
StoreModule.forFeature('orders', ordersReducer),
我的主減速機map:
const reducers: ActionReducerMap<AppState> = {
order: orderReducer,
admin: adminReducer,
tlabs: tlabsReducer,
reports: reportsReducer,
settings: settingsReducer,
orders: ordersReducer
};
然后是app.module中的主要導入:
StoreModule.forRoot(reducers),
嘗試讀取實體:
構造函數:
private store: Store<AppState>
實際 function:
this.store
.select(ordersReducer.selectAll)
該導入的來源:
import * as ordersReducer from '../../../../../store/reducers/orders.reducer';
我在 entity.js(NGRX 實現文件)中遇到了與您類似的錯誤。 就我而言,我有一個延遲加載的模塊,它有自己的 state,最初是未定義的。 由於實體選擇器在獲取實體相關字段(例如 ids)之前不執行任何 null 檢查,因此會導致此錯誤。 我的解決方案是避免使用orderAdapter.getSelectors(OrdersState)
而是定義我自己的相當簡單的受保護選擇器:
export const selectIds = createSelector(selectOrderState, (state) => state?.ids);
export const selectEntities = createSelector(selectOrderState, (state) => state?.entities);
export const selectAll = createSelector(selectOrderState, (state) => (state?.ids as Array<string|number>)?.map(id => state?.entities[id]));
export const selectTotal = createSelector(selectOrderState, (state) => state?.ids?.length);
我不喜歡我沒有使用內置選擇器的事實,但至少這不會破壞我的代碼。 我希望 NGRX 團隊提供一種方法來避免這種情況。
我遇到了這個錯誤,因為我使用錯誤的功能鍵設置了我的選擇器:
export const selectIocState = createFeatureSelector<fromIoc.IocState>('this_key_was_wrong');
它應該與您在功能模塊中加載的內容相匹配:
StoreModule.forFeature('feature_key', iocReducer),
看起來它在初始化之前嘗試從OrdersState
中讀取。 您的減速器實際上並沒有返回默認的 state 來初始化它; 至少您似乎沒有,在您提供的代碼中。
讓你的減速器返回默認的 state。
export function ordersReducer(
state: AllOrdersState = initialState,
action: actions.OrdersActions
) {
switch(action.type) {
case actions.CREATE_MANY: {
console.log(action.orders);
return orderAdapter.addMany(action.orders, state);
}
default: {
return state // Here you should return the default state
}
}
}
當我忘記將“狀態”作為 adapter.addOne() 的第二個參數添加時,我遇到了同樣的錯誤。 因此,在 OPs 示例中,如果 redcuer 是按以下方式編寫的:
return orderAdapter.addMany(action.orders); // !! lack of "state" as 2nd param
那么錯誤將完全相同。 就我而言,這是:
Uncaught TypeError: Cannot read properties of undefined (reading 'ids')
at Object.operation [as addOne] (entity.js?9b56:59:1)
at eval (eval at <anonymous> (mapping-fields-group.reducer.ts?fd4f:1:1), <anonymous>:1:17)
at eval (mapping-fields-group.reducer.ts?fd4f:13:1)
at eval (store.js?d450:1204:1)
at combination (store.js?d450:215:1)
at mappingsDataReducers (mappings-data-state.ts?7c86:21:1)
at eval (store.js?d450:265:1)
at combination (store.js?d450:215:1)
at eval (store.js?d450:254:1)
at computeNextEntry (store-devtools.js?777a:445:1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.