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.