How does the parent component re-execute a function after a Svelte child component changes?

I have a svelte code.I want to implement a function that the parent component re-executes after the child component is updated.
I am facing a problem now.After the child component is updated, the parent component function is re-triggered, but it will enter an infinite loop.

parent component

<script lang="ts">
  import { Button } from "$lib/components/ui/button";
  import { SquarePlus } from "lucide-svelte";
  import Datatable from "$lib/components/datatable/datatable.svelte";
  import { getUserListAPI } from "@/apis/hook";
  import type { User, UserFilter } from "@/interfaces/user";
  import { onMount } from "svelte";
  let data: User[] = [];
  let dataSize = 0;
  //demo data
  const data: Payment[] = [
    {
      id: "m5gr84i9",
      amount: 316,
      status: "Success",
      email: "[email protected]"
    },
    {
      id: "3u1reuv4",
      amount: 242,
      status: "Success",
      email: "[email protected]"
    },
    {
      id: "derv1ws0",
      amount: 837,
      status: "Processing",
      email: "[email protected]"
    },
    {
      id: "5kma53ae",
      amount: 874,
      status: "Success",
      email: "[email protected]"
    },
    {
      id: "bhqecj4p",
      amount: 721,
      status: "Failed",
      email: "[email protected]"
    }
  ]
  let tableFilterDetail:UserFilter = {
    pageIndex:1,
    pageLimit:10
  }
  const getData = async (req:UserFilter) => {
    //AXIOS post get remote data
    const res = await getUserListAPI(req);
    data = res.data.rows;
    dataSize = res.data.count;
  };
  onMount(()=>{
    getData(tableFilterDetail)
  })
  $:{
    getData(tableFilterDetail)
  }
</script>

<div>
  <div class="mb-2 w-full flex justify-between items-center">
    <h2 class="text-2xl font-bold tracking-tight">User</h2>
    <div class="flex items-center">
      <Button
        variant="success"
        class="ml-1 h-10 w-28 flex items-center justify-center rounded-lg "
      >
        <SquarePlus size="16" />New
      </Button>
    </div>
  </div>
  <Datatable {data} {columns} {dataSize} bind:tableFilterDetail/>
</div>

child component

<script lang="ts">
......

  //update state and update tableAttr
  $: {
    datatableAttr.update((state) => ({
      ...state,
      hiddenColumn: hideForId,
    }));
    datatableAttr.update((state) => ({
      ...state,
      dataSize: dataSize,
    }));
    datatableAttr.update((state) => ({
      ...state,
      pageSize: pageSize,
    }));
    tableFilterDetail = {
      pageIndex: $datatableAttr.currentPage,
      pageLimit: $datatableAttr.pageSize.value,
    };
    tableData.set(data);
  }

</script>
......
    <div class="flex items-center space-x-2">
      <label for="itemsPerPage" class="text-gray-700">Page shows:</label>
      <Select.Root portal={null} bind:selected={pageSize}>
        <Select.Trigger class="w-[130px]">
          <Select.Value />
        </Select.Trigger>
        <Select.Content>
          <Select.Group>
            {#each tableSize as size}
              <Select.Item value={size.value} label={size.label}
                >{size.label}</Select.Item
              >
            {/each}
          </Select.Group>
        </Select.Content>
        <Select.Input name="" />
      </Select.Root>
    </div>
    <div class="flex items-center space-x-2">
      <Pagination.Root
        count={$datatableAttr.dataSize}
        perPage={$datatableAttr.pageSize.value}
        let:pages
        let:currentPage
        bind:page={$datatableAttr.currentPage}
      >
        <Pagination.Content>
          <Pagination.Item>
            <Pagination.PrevButton />
          </Pagination.Item>
          {#each pages as page (page.key)}
            {#if page.type === "ellipsis"}
              <Pagination.Item>
                <Pagination.Ellipsis />
              </Pagination.Item>
            {:else}
              <Pagination.Item>
                <Pagination.Link {page} isActive={currentPage == page.value}>
                  {page.value}
                </Pagination.Link>
              </Pagination.Item>
            {/if}
          {/each}
          <Pagination.Item>
            <Pagination.NextButton />
          </Pagination.Item>
        </Pagination.Content>
      </Pagination.Root>
    </div>
......

It can be realized that the API is requested when the component is first loaded, and the API is requested again and the table data is updated when the table data changes.It won’t enter an infinite loop.