I have a list of products that needs to be displayed on page load and/or after adding it in a form. Also the list has a “load more” button that can fetch more data when clicked. What’s the proper way to do that in Remix? I added a fetcher.load
but seems its not reflecting the changes on the list UI
Please see my code below:
export async function loader({ context }: LoaderFunctionArgs) {
const url = new URL(request.url);
const offset = url.searchParams.get("offset") || 0;
const { products, count } = await getProducts({
limit: 10,
offset,
});
return {
products,
count: count.aggregate?.count,
};
}
export default function UploadProductsRoute() {
let { products } = useLoaderData<typeof loader>();
const fetchers = useFetchers();
let fetcher = useFetcher();
const optimisticProducts = fetchers.reduce<[]>((memo, f) => {
if (f.formData) {
const data = (Object.fromEntries(f.formData));
if (!products.map((e) => e.id).includes(data.id)) {
memo.push(data);
}
}
return memo;
}, []);
products = [...products, ...optimisticProducts];
return (
<div>
<div>
<div>
<h1>Add products</h1>
</div>
<AddProductForm />
<div>
<h1>Products you've added</h1>
</div>
<div>
<div>
{products.map((product) => (
<ProductItem key={product.id} name={product.name} description={product.description} />
))}
</div>
</div>
<div>
<Button onClick={() => {
const query = `?offset=${products.length}`;
fetcher.load(query);
}}>Load more</Button>
</div>
</div>
</div>
);
}