使用场景
管理比较多的数据,包括增删改查。
一般情况下,前端处理数据列表会使用数组格式,例如:
js
//数组格式的数据列表
const list = [
{id:1,age:'20',name:'A'},
{id:2,age:'22',name:'B'},
...+100
]
如果数据量很大,CURD操作时就会比较繁琐,性能较低。例如修改id为2的数据,每次修改需要遍历数组找到对应的数据后再进行修改。
createEntityAdapter的作用
createEntityAdapter是redux-toolkit提供的一个api,用来简化上述场景的操作。 将数组列表修改为便于操作的数据格式:
js
{
// id数组
ids: [1,2,...]
// 对应id的数据
entities: {
1:{id:1,age:'20',name:'A'},
2:{id:2,age:'22',name:'B'},
...+100
}
}
依然是更新操作为例,只需要读取entities对应id的数据进行修改。
使用方法
- 创建,接收参数可以设置id的字段名,以及根据entities对象获取数组的排序方式
feature/user.js
import {createSlice,createEntityAdapter} from "@reduxjs/toolkit";
//创建
const componentsAdapter = createEntityAdapter({
selectId: (component) => component.id,
sortComparer: (a, b) => a.zIndex - b.zIndex,
});
- 初始化,可以传入除了内置的ids和entities之外的其他state
js
const initialState = componentsAdapter.getInitialState({
activeComponentIds: [], //此时的initialState:{ids:[],entities:{},activeComponentIds:[]}
});
- 传入Slice并定义reducers。内置了常用的增删改查的方法
示例:
js
const componentsListSlice = createSlice({
name: "componentsList",
initialState, // {ids:[],entities:{'id1':{} } }
reducers: {
addComponent:(state,action){
componentsAdapter.addOne(state,action.payload)
},
updateComponent:(state,action){
componentsAdapter.opdateOne(state,{
id:action.payload.id,
changes: action.payload,
})
}
}
})
注意update相关的操作,对数据进行的浅拷贝,因此如果数据结构包含嵌套的引用类型,需要注意先对数据进行深拷贝,或明确传入需要修改的字段,避免影响。例如:
js
updateComponentStyleConfig: {
reducer: (state, action: PayloadAction<Partial<ComponentItem>>) => {
const { id, ...rest } = action.payload;
componentsAdapter.updateOne(state, {
id,
changes: {
style: {
...state.entities[id].style,
...rest,
},
},
});
}
读取state
内置getSelectors()函数,返回多种读取数据的方式

js
export const { selectAll: allComponents, selectById: selectComponentById } =
componentsAdapter.getSelectors((state) => state.componentList);
可以结合createSelector缓存计算后的state值
js
const activeComponentId = createSelector(
(state) => {
return state.componentList.activeComponentIds;
},
(ids) => {
return ids.length === 1 ? ids[0] : "";
},
);