Data Loading
Unanswered
Blue Picardy Spaniel posted this in #help-forum
Blue Picardy SpanielOP
# Code
# Issue
The loader never shows.
# Notes
- If I add a wait, the loader shows.
-
"use client";
import { Loader2, RefreshCw } from "lucide-react";
import { Button } from "@/components/ui/button";
import type { User } from "@db/schema";
import { getUserGuilds } from "@/lib/discord-api";
import { set } from "@/app/dashboard/guilds-slice";
import { useDispatch } from "react-redux";
import { useState } from "react";
import { useToast } from "@/components/ui/use-toast";
export default function RefreshGuilds({ user }: { user: User }) {
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const { toast } = useToast();
async function refreshGuilds() {
setLoading(true);
if(!user) {
setLoading(false);
return toast({ description: "Something went wrong!", variant: "destructive" });
}
getUserGuilds().then(userGuilds => {
if(userGuilds) {
dispatch(set(userGuilds));
toast({ description: "Guilds refreshed" });
}
if(!userGuilds) toast({ description: "Something went wrong!", variant: "destructive" });
setLoading(false);
});
}
return (
<form action={refreshGuilds}>
<Button variant="outline" disabled={loading}>
{loading ? <Loader2 className="mr-2 h-5 w-5 animate-spin" /> : <RefreshCw className="mr-2 h-5 w-5" />}
<span className="text-base">Refresh</span>
</Button>
</form>
);
}# Issue
The loader never shows.
# Notes
- If I add a wait, the loader shows.
-
true is printed twice and false is printed twice when I click the button.12 Replies
Sloth bear
toast({ description: "Guilds refreshed" });
Does this toast pop up?
Does this toast pop up?
@Sloth bear toast({ description: "Guilds refreshed" });
Does this toast pop up?
Blue Picardy SpanielOP
yeah
U want the loading state to work?
'use client'
import { useFormStatus } from 'react-dom'
export function SubmitButton() {
const { pending } = useFormStatus()
return (
<button type="submit" disabled={pending}>
Add
</button>
)
}@Blue Picardy Spaniel yeah
Sloth bear
Try to force re-render
setLoading(true);
await new Promise(resolve => setTimeout(resolve, 0));
getUserGuilds().then(userGuilds => {
if (userGuilds) {
dispatch(set(userGuilds));
toast({ description: "Guilds refreshed" });
} else {
toast({ description: "Something went wrong!", variant: "destructive" });
}
setLoading(false);
});@Sloth bear Try to force re-render
setLoading(true);
await new Promise(resolve => setTimeout(resolve, 0));
getUserGuilds().then(userGuilds => {
if (userGuilds) {
dispatch(set(userGuilds));
toast({ description: "Guilds refreshed" });
} else {
toast({ description: "Something went wrong!", variant: "destructive" });
}
setLoading(false);
});
Blue Picardy SpanielOP
yeah this forces the re-render
Sloth bear
Or you can do it like that:
getUserGuilds().then(userGuilds => {
setTimeout(() => {
if (userGuilds) {
dispatch(set(userGuilds));
toast({ description: "Guilds refreshed" });
} else {
toast({ description: "Something went wrong!", variant: "destructive" });
}
setLoading(false);
}, 500);
});If it did helped you don't forget to
Mark SolutionBlue Picardy SpanielOP
this isn't really the proper way to do it tho
i want to do it the way its intended instead of using workarounds
Sloth bear
Ahm try this then:
export default function RefreshGuilds({ user }: { user: User }) {
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const { toast } = useToast();
const refreshGuilds = async () => {
setLoading(true);
if (!user) {
setLoading(false);
return toast({ description: "Something went wrong!", variant: "destructive" });
}
try {
const userGuilds = await getUserGuilds();
if (userGuilds) {
dispatch(set(userGuilds));
toast({ description: "Guilds refreshed" });
} else {
toast({ description: "Something went wrong!", variant: "destructive" });
}
} catch (error) {
toast({ description: "Failed to fetch guilds!", variant: "destructive" });
} finally {
setLoading(false);
}
};
useEffect(() => {
refreshGuilds();
}, [user]);
return (
<form onSubmit={(e) => {
e.preventDefault();
refreshGuilds();
}}>
<Button variant="outline" disabled={loading}>
{loading ? <Loader2 className="mr-2 h-5 w-5 animate-spin" /> : <RefreshCw className="mr-2 h-5 w-5" />}
<span className="text-base">Refresh</span>
</Button>
</form>
);
}Don't forget to import useEffect hook