Abort queries before unmount
DavidNguyen67 opened this issue · 2 comments
DavidNguyen67 commented
userApi.slice.ts
export const userApi = createApi({
baseQuery: axiosBaseQuery(),
tagTypes: [QUERY_TAG.USER, QUERY_TAG.COUNT_USER],
endpoints: (build) => ({
getUsers: build.query<UserEntity[] | null, ListUserDto>({
queryFn: async (payload, _queryApi, _extraOptions, baseQuery) => {
try {
const data = await userService.listUsers(payload, {});
return { data };
} catch (error) {
return { error };
}
},
providesTags: (result, error, arg) =>
result && result?.length > 0
? [
...result.map(({ id }) => ({
type: QUERY_TAG.USER as const,
id,
})),
QUERY_TAG.USER,
]
: [QUERY_TAG.USER],
}),
countUsers: build.query<number | null, undefined>({
queryFn: async (_, _queryApi, _extraOptions, baseQuery) => {
try {
const data = await userService.countUser({});
return { data };
} catch (error) {
return { error };
}
},
providesTags: (result, error, arg) => [QUERY_TAG.COUNT_USER],
}),
registerUses: build.mutation<string | null, CreateUserDto>({
queryFn: async (payload, _queryApi, _extraOptions, baseQuery) => {
const { signal } = _queryApi;
try {
const data = await userService.generateUser(payload, { signal });
return { data };
} catch (error) {
return { error };
}
},
invalidatesTags: [QUERY_TAG.USER, QUERY_TAG.COUNT_USER],
}),
}),
});
Component.tsx
let promise: any;
const Home = () => {
const { data } = useGetUsersQuery({
offset: 0,
limit: 30,
});
const { data: count } = useCountUsersQuery(undefined, {
pollingInterval: API_TIME_POLLING,
});
// Define the columns for the table
const columns: TableProps<UserEntity>['columns'] = useMemo(
() => [
{
title: '#',
dataIndex: 'index',
render: (text, record, index) => index + 1,
width: 15, // Thiết lập chiều rộng cho cột số thứ tự
align: 'center',
fixed: 'left',
},
{
title: 'Email',
dataIndex: 'email',
width: 200, // Thiết lập chiều rộng cho cột email
},
{
title: 'Name',
dataIndex: 'name',
render: (text, record) => `${record.firstName} ${record.lastName}`,
width: 150, // Thiết lập chiều rộng cho cột tên
},
],
[]
);
const [addUser, { isLoading, error }] = useRegisterUsesMutation();
const handleGenerateAnUser = useCallback(async () => {
try {
const payload: CreateUserDto = {
email: faker.internet.email(),
firstName: faker.person.firstName(),
id: faker.string.uuid(),
lastName: faker.person.lastName(),
};
if (promise) {
promise.abort();
promise = null;
}
promise = addUser(payload);
await promise.unwrap();
console.log('User added:', promise);
} catch (error) {
console.error('Failed to add user:', error);
}
}, [addUser]);
const handleAbortQuery = useCallback(() => {
promise.abort();
promise = null;
}, []);
useEffect(() => {
return () => {
if (promise) {
promise.abort();
promise = null;
}
};
}, []);
return (
<>
<Button
type='primary'
onClick={handleGenerateAnUser}
// loading={isLoading}
>
Generate a user
</Button>
<Button
danger
disabled={!promise}
onClick={handleAbortQuery}
>
Abort query
</Button>
{data && data?.length > 0 && (
<>
<Table
columns={columns}
dataSource={data}
rowKey={'id'}
loading={isLoading}
size='small'
sticky
// pagination={{
// defaultPageSize: 5,
// pageSizeOptions: [10, 20, 50, 100],
// }}
bordered
/>
</>
)}
</>
);
};
export default Home;
anyone can help me?
to optimize it ? like define type for var promise
?
markerikson commented
The question is very unclear, and this appears to be A) about Redux Toolkit (not the Redux core library), and B) a usage question. Could you ask this in the "Discussions" section of https://github.com/reduxjs/redux-toolkit instead?
DavidNguyen67 commented
I want to proactively abort a query in a React component when necessary. At the same time, I want to use useEffect to ensure that the query will be canceled when the component is unmounted.
BTW, thank for show me where i can disscus