0

I retrieve an array from database and set it to my slice.

[ { id: 'a01', name: 'name01' }, { id: 'a02', name: 'name02' }, { id: 'a03', name: 'name03' } ];

Users change the order with a user interface. When they change the order of the objects reorder reducer runs. It is a simple function which changes the positions of two objects inside array. Then boardAdapter.setAll sets the whole data.

Actually it works properly, but i realized an odd behaviour when all chars of id field are numbers as below. (e.g. id: '1' or id: '1234')

[ { id: '1', name: 'name01' }, { id: 'a02', name: 'name02' }, { id: 'a03', name: 'name03' } ];

This time reordering process works again properly but when it comes to returning that 'ordered' data and boardAdapter.setAll step, i see that ids being updated but entities still remain same.

Before reordering / After reordering

enter image description here

import { createSlice, createAsyncThunk, createEntityAdapter } from '@reduxjs/toolkit';
const boardAdapter = createEntityAdapter({});

export const reorder = createAsyncThunk('board/reorder', async ({ result, sections }) => {
    const { source, destination } = result;
    const ordered = reorderSection(sections, source.index, destination.index);
    return ordered;
});

const reorderSection = (sections, startIndex, endIndex) => {
    const result = Array.from(sections);
    const [removed] = result.splice(startIndex, 1);
    result.splice(endIndex, 0, removed);

    return result;
};

const boardSlice = createSlice({
    name: 'board',
    reducers: {
        resetBoard: (state, action) => null,
    }
    extraReducers: {
        [reorder.fulfilled]: boardAdapter.setAll
    }
});

I appreciate if anyone knows the reason. Thank you for your support.

Er.Se
  • 461
  • 3
  • 11

1 Answers1

1

The order of keys in a JavaScript object like your entities cannot be relied on depending on the engine you are working on and constructing a new object with the right order can be especially ticky - and so entityAdapter will not ever change it and just leave any random order (usually order of insertion).

The only source of "ordering" is the ids array - and using the selectors of your entityAdapter will give you the contents back, mapped into the right order.

phry
  • 35,762
  • 5
  • 67
  • 81
  • export const { selectAll: selectAllSections, selectById: selectSectionById } = boardAdapter.getSelectors( state => state.board ); In a function I use it that way: "const sections = useSelector(selectAllSections)" after importing selector. – Er.Se Sep 10 '21 at 07:10
  • ...but i don't know how to use selector inside a reducer. – Er.Se Sep 10 '21 at 07:11
  • `selectAllSections(state)` - but order should usually not play a role in reducers, but in selectors, as ordered stuff is suially "derived data" that should not be part of your state. https://redux.js.org/recipes/computing-derived-data – phry Sep 10 '21 at 08:37