Search code examples
redux-toolkitrtk-query

access RTK-query data in createSlice action


what woud be the correct way to access RTK-query data inside createSlice reducers?

Like, for example 'select all' functionality in the code below.

is it possible to access current useGetOrdersQuery() data inside toggleSelectAll() action?

or the only/best way to implement 'select/deselect all' would be to pass useGetOrdersQuery() data to toggleSelectAll() action as action payload?

dashboardSlice.js

const initialState = {
  selectedIds: [],
};
export const dashboardSlice = createSlice({
  name: 'dashboard',
  initialState,
  reducers: {
    toggleSelectAll: (state, action) => {
       //get "useGetOrdersQuery" data id's and assign to state.selectedIds
    }
  }
});

export const { toggleSelectAll } = dashboardSlice.actions;
export const selectSelectedIds = state => state.dashboard.selectedIds;

orders-lsit.js

import { useGetOrdersQuery } from './api'
import { toggleSelectAll, selectSelectedIds } from './dashboardSlice';

const OrdersList = () => {
  const {data} = useGetOrdersQuery(123);
  const dispatch = useDispatch();
  const selectedIds = useSelector(selectSelectedIds);

  return (
    <div>
      <button onClick={() => dispatch(toggleSelectAll())}>
        select/deselect all
      </button>
      {data.map(o => (
        <div>
          <h2>{o.name}</h2>
          <input 
            type="checkbox"
            checked={selectedIds.includes(o.id)}
          />
        </div>
      ))}
    </div>
  )
}
 

api.js

export const api = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  endpoints: (builder) => ({
    getOrders: builder.query({
      query: (userId) => `${userId}/orders`,
      providesTags: [{ type: 'Orders', id: 'LIST' }]
    })
  })
});

export const { useGetOrdersQuery } = api;


Solution

  • if you just want to save the ids you can do this :

    const initialState = {
      selectedIds: [],
    };
    export const dashboardSlice = createSlice({
      name: 'dashboard',
      initialState,
      reducers: {
        toggleSelectAll: (state, action) => {
           //get "useGetOrdersQuery" data id's and assign to state.selectedIds
           const { ids }  = action.payload;
           state.selectedIds = ids;
           return state;
        }
      }
    });
    
    export const { toggleSelectAll } = dashboardSlice.actions;
    export const selectSelectedIds = state => state.dashboard.selectedIds;
    

    and

    import { useGetOrdersQuery } from './api'
    import { toggleSelectAll, selectSelectedIds } from './dashboardSlice';
    
    const OrdersList = () => {
      const {data} = useGetOrdersQuery(123);
      const dispatch = useDispatch();
      const selectedIds = useSelector(selectSelectedIds);
    
    
      // you can pass the list of ids as a payload to your action and store it for later use.
      return (
        <div>
          <button onClick={() => dispatch(toggleSelectAll({ids: data.map(item => item.id}))}>
            select/deselect all
          </button>
          {data.map(o => (
            <div>
              <h2>{o.name}</h2>
              <input 
                type="checkbox"
                checked={selectedIds.includes(o.id)}
              />
            </div>
          ))}
        </div>
      )
    }
    

    you have something like this too: check out this link

    const store = useStore();
    const allDataOfAllQueries = store.getState().api.queries;
    console.log(Object.values(allDataOfAllQueries);