RTK Query pagination not working with custom baseQuery and createApiAdapter
I created a react application with RTK Query
to build a generic base query for a project but I faced an issue the creatSelector
method because the selectors it creates don't update the ids and entitle the array when the data changes
Store
import { configureStore } from "@reduxjs/toolkit";
import { apiSlice, authSlice, genericSlice } from "../features/api/apiSlice";
export const store = configureStore({
reducer: {
[apiSlice.reducerPath]: apiSlice.reducer,
[authSlice.reducerPath]: authSlice.reducer,
[genericSlice.reducerPath]: genericSlice.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware()
.concat(apiSlice.middleware)
.concat(authSlice.middleware)
.concat(genericSlice.middleware),
devTools: true,
});
Custom base query
import { BaseQueryFn } from "@reduxjs/toolkit/dist/query";
export const genericBaseQuery =
(): BaseQueryFn<any, unknown, unknown> => async (fn: any) => {
try {
const result = await fn;
return {
data: {
data: result,
success: true,
message: result,
},
};
} catch (error) {
throw new Error("errrorrrrsss");
}
};
API slice
export const genericSlice = createApi({
reducerPath: "genericApi",
tagTypes: ["bookingRecords"],
baseQuery: genericBaseQuery(),
endpoints: (builder) => ({}),
});
Booking records slice
const bookingRecordsAdapter = createEntityAdapter({
selectId: (bookingRecord: any) => bookingRecord.id,
});
const initialState = bookingRecordsAdapter.getInitialState();
export const extendedApiSlice = genericSlice.injectEndpoints({
endpoints: (builder) => ({
listBookingRecords: builder.query({
query: (request: FindBookingRecords) =>
axiosApi.findBookingRecords(request),
transformResponse: (response: any) => {
const changedBookingRecords: IBookingRecordResponse[] =
response.data.data.bookingRecords;
return bookingRecordsAdapter.setAll(
initialState,
changedBookingRecords
);
},
async onQueryStarted(
{ pagination, filter, sort, ...patch },
{ dispatch, queryFulfilled }
) {
console.log("fsafasfasfa")
const patchResult = dispatch(
extendedApiSlice.util.updateQueryData(
"listBookingRecords",
{ pagination, filter, sort },
(draft) => {
console.log("draft", draft);
console.log("patch", patch);
Object.assign(draft, patch);
}
)
);
try {
await (await queryFulfilled).data;
} catch {
extendedApiSlice.util.invalidateTags(["bookingRecords"])
patchResult.undo();
/**
* Alternatively, on failure you can invalidate the corresponding cache tags
* to trigger a re-fetch:
* dispatch(api.util.invalidateTags(['Post']))
*/
}
},
providesTags: (result: any) => [
{ type: "bookingRecords", id: "LIST" },
...result.ids.map((id: any) => ({ type: "bookingRecords", id })),
],
}),
listBookingRecordById: builder.query({
query: (request: FindBookingRecord) =>
axiosApi.findBookingRecord(request),
transformResponse: (response: any) => {
const changedBookingRecord: IBookingRecordResponse = response.data.data;
return changedBookingRecord;
},
}),
addBookingRecord: builder.mutation({
list
export default function BookingRecordsList() {
const [pageSize, setPageSize] = useState<number>(10);
const [offset, setOffset] = useState<number>(0);
const { data, isError, isLoading, isSuccess, isFetching, originalArgs } =
useListBookingRecordsQuery({
pagination: { limit: pageSize, offset: offset },
});
const navigate = useNavigate();
const bookingRecordIds = useSelector(selectBookingRecordsIds);
console.log("data", data);
console.log("bookingRecordIds", bookingRecordIds);
console.log("originalArgs", originalArgs);
const [signOut, { isLoading: signOutLoading }] = useSignOutMutation();
const canSignOut = !signOutLoading;
const test = () => {
if (isLoading || isFetching) {
return <div>loading...</div>;
}
if (isSuccess) {
return bookingRecordIds?.map((id: any) => {
return <BookingRecordListItem id={id.toString()} key={id} />;
});
}
if (isError) {
return <div>error</div>;
}
};
const onSignOutClicked = async () => {
if (canSignOut) {
try {
await signOut({}).unwrap();
navigate("/signIn");
} catch (err) {
console.error("Failed to sign out", err);
}
开发者_如何学JAVA }
};
return (
<div>
<button
onClick={() => {
navigate("/bookingRecords/add");
}}
style={{ padding: "5px", margin: "10px" }}
>
add booking record
</button>
<select
onChange={(e) => {
let offset = parseInt(e.target.value);
setOffset(Math.abs((offset - 1) * pageSize));
}}
style={{ padding: "5px", margin: "10px" }}
>
<option value={0}>0</option>
<option value={1}>1</option>
<option value={2}>2</option>
<option value={3}>3</option>
<option value={4}>4</option>
</select>
<button
onClick={onSignOutClicked}
style={{ padding: "5px", margin: "10px" }}
>
signOut
</button>
{test()}
{/* <button onClick={() => addUser({ iata: "tst", name: "test" })}>
add user
</button> */}
</div>
);}
when i fetch the data for the first time every thing works fine. when i change the offset a request is sent and the new data is fetched but the ids array and entities array didnt change keeping the old data even the the data got from the hook is updated
精彩评论