如何在Redux中使用createEntityAdapter将数组设为初始数据
解决方案
你要实现预置初始数据的需求,推荐按优先级从高到低选以下两种方案:
方案1:直接在eventSlice初始化时注入默认数据(最推荐)
这种方式在store初始化阶段就把默认数据写入,完全满足「其他方法访问前完成数据添加」的要求,无需额外调用逻辑。
修改后的eventSlice.ts代码如下:
import { createEntityAdapter, createSlice, EntityAdapter, } from "@reduxjs/toolkit"; import { RootState } from "../store"; // 导入预置数据 import { getAllEvents } from "../../../dummy-data"; export type EventType = { id: string; title: string; description: string; location: string; date: string; image: string; isFeatured: boolean; }; const eventAdapter: EntityAdapter<EventType> = createEntityAdapter<EventType>({ // sortComparer: (a: EventType, b: EventType) => b.date.localeCompare(a.date), }); // 初始化时直接把预置数据写入adapter const initialState = eventAdapter.addMany( eventAdapter.getInitialState({ status: "idle", error: null, }), getAllEvents() ); export const eventSlice = createSlice({ name: "event", initialState, reducers: { eventLoading(state, action) { if (state.status === "idle") { state.status = "pending"; } }, eventCleaded: eventAdapter.removeAll, eventAdded: eventAdapter.addOne, eventUpdated: eventAdapter.updateOne, // 可按需添加批量新增的action eventAddedMany: eventAdapter.addMany, }, }); export const eventSelector = eventAdapter.getSelectors<RootState>( (state) => state.events ); export const { eventAdded, eventCleaded, eventLoading, eventUpdated, eventAddedMany } = eventSlice.actions; export default eventSlice.reducer;
方案2:业务层手动初始化(适用不能在slice层引入dummy-data的场景)
你当前的写法有两个问题:
useAppDispatch是React Hook,不能在普通函数中调用,会违反Hook调用规则- 循环调用
eventAdded单条插入效率低,应该用批量插入接口
首先按方案1的代码先在eventSlice里添加eventAddedMany: eventAdapter.addMany这个reducer,然后在项目根组件(比如App.tsx)中加初始化逻辑,保证应用加载时只执行一次:
import { useEffect } from 'react' import { getAllEvents } from "../../../dummy-data"; import { useAppDispatch } from "../hooks"; import { eventAddedMany } from "./eventSlice"; function App() { const dispatch = useAppDispatch() useEffect(() => { // 批量插入预置数据,仅执行一次 dispatch(eventAddedMany(getAllEvents())) }, [dispatch]) // 其他原有逻辑 return <div>/* 你的应用内容 */</div> }
如果你的预置数据是需要异步请求获取的,配合createAsyncThunk写异步逻辑,在store初始化后触发一次请求即可。
内容的提问来源于stack exchange,提问作者user16911633
相关产品推荐
相关产品推荐

