我们如何根据 table 列对 createEntityAdapter 的实体进行排序?

How can we sort entites of createEntityAdapter based on table columns?

我在我的 React 应用程序中使用 Redux-toolkit with entityAdapter 进行状态管理。我想对每一列应用 table 排序,其中我的 table 行是 Redux-toolkit entityAdapter 的实体。我想在我的 reducer 中像这样更改 sortComparer 函数。

sortEntities: (state,action) =>{
return {
...state,
sortComparer:(a:myEntityType,b:myEntityType)=> a.title.localCompare(b.title)
};
},

我在列的 onClick 处理程序上调度 sortEntities 操作。这种更改 sortComparer 不会抛出任何规则破坏错误但不起作用。有人可以帮助我吗?

你在上面的代码中所做的是将 function 存储到你所在州的 sortComparer 属性。您实际上并没有在任何地方应用排序函数,并且不建议像 Redux 中的函数那样存储不可序列化的数据。

您通过调用 createEntityAdapter 创建的适配器是一个帮助您与状态交互的对象。状态本身只是一个 ids 的数组和 entities 的字典对象。 adapter的sortComparer属性不是state的一部分,所以不能通过修改state来修改。


有很多方法可以解决这个问题。

例如,您可以 select Redux 的所有实体并在本地对它们进行排序。

const useSortedEntities = (sortBy) => {
   // get an array of entities with the selector from the entity adapter
   const allEntities = useSelector(selectEntities);

   // sort based on the current property
   // use ... to avoid mutation
   // would probably want to memoize this
   return [...allEntities].sort(
     (a, b) => a[sortBy].localCompare(b[sortBy])
   );
}
const SomeComponent = () => {
   const [sortProperty, setSortProperty] = useState('author');

   const sortedList = useSortedEntities(sortProperty);
...

或者您可以 dispatch 在负载中使用排序 属性 的操作,并将排序 属性 保存在 Redux 中。然后,您可以使用 createSelector 为排序后的数据创建 selector。

const mySlice = createSlice({
    name: 'someName',
    initialState: myAdapter.getInitialState({
       // additional properties to include in initial state
       sortBy: 'author'
    }),
    reducers: {
       sortEntities: (state, action: PayloadAction<string>) => {
           state.sortBy = action.payload;
       }
...
const selectSortedEntities = createSelector(
   // first select entities with the selector from the adapter
   selectEntities,
   // next select the sort order
   (state: RootState) => state.pathToSlice.sortBy
   // then combine them to return a sorted array
   (allEntities, sortBy) => [...allEntities].sort(
        (a, b) => a[sortBy].localCompare(b[sortBy])
   );
)
const SomeComponent = () => {
   const sortedList = useSelector(selectSortedEntities);
   
   const dispatch = useDispatch();
   
   const onClick = () => {
       dispatch(sortEntities('title'));
   }
...