Redux Toolkit createEntityAdapter:如何获取适配器的当前状态?
Redux Toolkit createEntityAdapter: how can i get current state of adapter?
我在尝试将状态传递到 entityAdapter CRUD 函数时看到 TS 类型错误
实时沙箱(错误行被注释掉):
https://codesandbox.io/s/createentityadapter-demo-5rvl4
创建书籍适配器
const booksAdapter = createEntityAdapter<Book>({
selectId: (book) => book.bookId,
sortComparer: (a, b) => a.title.localeCompare(b.title)
});
...创建切片并配置存储
const booksSlice = createSlice({
name: "books",
initialState: booksAdapter.getInitialState(),
reducers: {
// Can pass adapter functions directly as case reducers. Because we're passing this
// as a value, `createSlice` will auto-generate the `bookAdded` action type / creator
bookAdded: booksAdapter.addOne,
bookRemoved: booksAdapter.removeOne,
bookUpdated: booksAdapter.updateOne,
booksReceived(state, action) {
// Or, call them as "mutating" helpers in a case reducer
booksAdapter.setAll(state, action.payload.books);
}
}
});
export const store = configureStore({
reducer: {
books: booksSlice.reducer
}
});
...调度按预期工作
store.dispatch(bookAdded({ bookId: 1, title: "title 1" }));
store.dispatch(bookAdded({ bookId: 2, title: "title 2" }));
store.dispatch(bookAdded({ bookId: 3, title: "title 3" }));
但是当我检索存储状态并尝试在对 adapter.addOne 的命令式调用中使用它时出现错误(即不通过 reducer)
let storeState = store.getState();
console.log("storeState", storeState, typeof storeState);
// booksAdapter.addOne(storeState, { id: 4, title: "title 4" });
console.log 的 storeState 看起来像一个有效的对象...
storeState
{books: Object}
books: Object
ids: Array(3)
0: 1
1: 2
2: 3
entities: Object
1: Object
2: Object
3: Object
object
但该行(注释掉)
booksAdapter.addOne(storeState, { id: 4, title: "title 4" });
导致 TS 错误:
let storeState: {
books: EntityState<Book>;
}
No overload matches this call.
Overload 1 of 2, '(state: EntityState<Book>, entity: Book): EntityState<Book>', gave the following error.
Argument of type '{ books: EntityState<Book>; }' is not assignable to parameter of type 'EntityState<Book>'.
我不明白为什么会出现不匹配的情况,因为我是直接通过商店。
我已经在 JS 中尝试过了,当然没有类型问题,而且它可以正常工作。那么我的问题是:如果不是 store.getState() 的结果,使用 TS 时传递给 CRUD 函数的正确状态对象是什么?
数据在storeState.books
,不在storeState
。
所以你需要打电话给
booksAdapter.addOne(storeState.books, { id: 4, title: "title 4" });
请注意,这不会修改您的状态,而只会为您提供所述状态的修改副本。您只能通过动作调度修改您的状态。
我在尝试将状态传递到 entityAdapter CRUD 函数时看到 TS 类型错误
实时沙箱(错误行被注释掉):
https://codesandbox.io/s/createentityadapter-demo-5rvl4
创建书籍适配器
const booksAdapter = createEntityAdapter<Book>({
selectId: (book) => book.bookId,
sortComparer: (a, b) => a.title.localeCompare(b.title)
});
...创建切片并配置存储
const booksSlice = createSlice({
name: "books",
initialState: booksAdapter.getInitialState(),
reducers: {
// Can pass adapter functions directly as case reducers. Because we're passing this
// as a value, `createSlice` will auto-generate the `bookAdded` action type / creator
bookAdded: booksAdapter.addOne,
bookRemoved: booksAdapter.removeOne,
bookUpdated: booksAdapter.updateOne,
booksReceived(state, action) {
// Or, call them as "mutating" helpers in a case reducer
booksAdapter.setAll(state, action.payload.books);
}
}
});
export const store = configureStore({
reducer: {
books: booksSlice.reducer
}
});
...调度按预期工作
store.dispatch(bookAdded({ bookId: 1, title: "title 1" }));
store.dispatch(bookAdded({ bookId: 2, title: "title 2" }));
store.dispatch(bookAdded({ bookId: 3, title: "title 3" }));
但是当我检索存储状态并尝试在对 adapter.addOne 的命令式调用中使用它时出现错误(即不通过 reducer)
let storeState = store.getState();
console.log("storeState", storeState, typeof storeState);
// booksAdapter.addOne(storeState, { id: 4, title: "title 4" });
console.log 的 storeState 看起来像一个有效的对象...
storeState
{books: Object}
books: Object
ids: Array(3)
0: 1
1: 2
2: 3
entities: Object
1: Object
2: Object
3: Object
object
但该行(注释掉)
booksAdapter.addOne(storeState, { id: 4, title: "title 4" });
导致 TS 错误:
let storeState: {
books: EntityState<Book>;
}
No overload matches this call.
Overload 1 of 2, '(state: EntityState<Book>, entity: Book): EntityState<Book>', gave the following error.
Argument of type '{ books: EntityState<Book>; }' is not assignable to parameter of type 'EntityState<Book>'.
我不明白为什么会出现不匹配的情况,因为我是直接通过商店。
我已经在 JS 中尝试过了,当然没有类型问题,而且它可以正常工作。那么我的问题是:如果不是 store.getState() 的结果,使用 TS 时传递给 CRUD 函数的正确状态对象是什么?
数据在storeState.books
,不在storeState
。
所以你需要打电话给
booksAdapter.addOne(storeState.books, { id: 4, title: "title 4" });
请注意,这不会修改您的状态,而只会为您提供所述状态的修改副本。您只能通过动作调度修改您的状态。