Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abort queries before unmount #4716

Closed
DavidNguyen67 opened this issue Jun 30, 2024 · 2 comments
Closed

Abort queries before unmount #4716

DavidNguyen67 opened this issue Jun 30, 2024 · 2 comments

Comments

@DavidNguyen67
Copy link

DavidNguyen67 commented Jun 30, 2024

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
Copy link
Contributor

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?

@markerikson markerikson closed this as not planned Won't fix, can't repro, duplicate, stale Jun 30, 2024
@DavidNguyen67
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants