Tsarsko Petrovich
Tsarsko Petrovich

Reputation: 31

Issue with resetting tanstack table state using redux

I have a tanstack table displaying some users. This table can be filtered. The current state of the filters is stored in a redux slice. Every time a filter changes, a http request is sent to the server to fetch the filtered users, and those are displayed on the table. This is working, except when I reset the state. For example, when I navigate to a different page and return to the users table, I want its state to set.

For that, I added an useEffect on the component where UsersTable is, dispatching the action resetting the state:

function UsersPage() {
  const dispatch = useDispatch();

  (...)

  useEffect(() => {
    dispatch(clearUsersList());
  }, []);


  return (
      (...)
      <UsersTable />
      (...)
  );
};

Here's UsersTable:

function UsersTable() {
  const role = useSelector(selectRoleFilter);
  const status = useSelector(selectStatusFilter);

  const [sorting, setSorting] = useState<SortingState>([
    { desc: true, id: 'createdAt' },
  ]);

  useEffect(() => {
    getUsers();
  }, [role, status, sorting]);

  const { tableUsers, getUsers } = useGetUsers({
    role,
    status,
    sorting,
  });

  const columns = useGetUsersTableColumns();

  const table = useReactTable({
    data: tableUsers,
    columns: columns,
    getCoreRowModel: getCoreRowModel(),
    manualSorting: true,
    onSortingChange: setSorting,
    state: {
      sorting,
    },
  });

  (...)  

  return (
      <div className="table-container overflow-x-auto w-full h-full">
        <TableList table={table} />  // actually renders the table
      </div>
  );
};

Here's useGetUsers:

function useGetUsers({ role, status, sorting }: GetUsersOptions) {
  const dispatch = useDispatch();

  const [tableUsers, setTableUsers] = useState<TableUser[]>([]);

  async function getUsers() {
    const { users } = await fetchUsers(role, status, sorting) // request to fetch users
    setTableUsers(formatUsersForTable(users));
    dispatch(setUsersCount(users?.length));
  };


  function formatUsersForTable(users: User[]) {
    (...)
  };

  return {
    tableUsers,
    getUsers,
  };
};

And here's userListSlice:

export const usersListSlice = createSlice({
  name: 'usersListSlice',
  initialState,
  reducers: {
    setRoleFilter: (state, action: PayloadAction<UserRole[]>) => {
      state.roleFilter = action.payload;
    },
    setStatusFilter: (state, action: PayloadAction<UserStatus[]>) => {
      state.statusFilter = action.payload;
    },
    setUsersCount: (state, action: PayloadAction<number>) => {
      state.usersCount = action.payload;
    },
    clearUsersList: () => {
      return initialState;
    },
  },
});

// Actions
export const { setRoleFilter, setStatusFilter, setUsersCount, clearUsersList } =
  usersListSlice.actions;

// Selectors
export const selectUsersCount = (state: RootState) =>
  state.usersList.usersCount;
export const selectRoleFilter = (state: RootState) =>
  state.usersList.roleFilter;
export const selectStatusFilter = (state: RootState) =>
  state.usersList.statusFilter;

The issue is after resetting the state, the table doesn't correctly update. The state itself is correctly reset, but the table keeps displaying the previously filtered users. For example, suppose initially there are 10 users, then a filter is applied that would result in only 4 being displayed. If I exit that page and return to it, I still see the 4, even when clearUsersList was executed. If I log tableUsers returned from useGetUsers, I see that I do get the 10 users in some moment, but then it reverts back to being 4.

What's the issue here?

Upvotes: 0

Views: 204

Answers (0)

Related Questions