formData.get is not a function with useFormState
Unanswered
Matt posted this in #help-forum
MattOP
'use client';
export default function InternalButton({ sendTo, alreadyFriends, alreadySentRequest, hasInboundRequest }: { sendTo: string, alreadyFriends: boolean, alreadySentRequest: boolean, hasInboundRequest: boolean }) {
const { pending } = useFormStatus();
let action: any
if (alreadyFriends) {
action = null;
} else if (alreadySentRequest) {
action = unsendFriendRequestAction;
} else if (hasInboundRequest) {
action = acceptFriendRequestAction;
} else {
action = sendFriendRequestAction;
}
const [state, formAction] = useFormState(action, undefined)
useEffect(() => {
if (state === 'error') {
toast.error("Error changing friend status!")
}
}, [state])
return (
#Unknown Channel
<input type="hidden" name="sendTo" value={sendTo} readOnly />
<button
aria-disabled={pending}
formAction={formAction}
>
{pending && <LoadingSpinner />}
{alreadyFriends && 'Friends'}
{alreadySentRequest && 'Unsend Friend Request'}
{hasInboundRequest && 'Accept Friend Request'}
{(!alreadyFriends && !alreadySentRequest && !hasInboundRequest) && 'Send Friend Request'}
</button>
</>
)
}```
This used to work when I just passed the action in the button formAction, but I switched it to useFormState and now I'm getting an error in the action that formData.get is not a function. When I console log formData, it's the state. Do I have something mixed up here?
export default function InternalButton({ sendTo, alreadyFriends, alreadySentRequest, hasInboundRequest }: { sendTo: string, alreadyFriends: boolean, alreadySentRequest: boolean, hasInboundRequest: boolean }) {
const { pending } = useFormStatus();
let action: any
if (alreadyFriends) {
action = null;
} else if (alreadySentRequest) {
action = unsendFriendRequestAction;
} else if (hasInboundRequest) {
action = acceptFriendRequestAction;
} else {
action = sendFriendRequestAction;
}
const [state, formAction] = useFormState(action, undefined)
useEffect(() => {
if (state === 'error') {
toast.error("Error changing friend status!")
}
}, [state])
return (
#Unknown Channel
<input type="hidden" name="sendTo" value={sendTo} readOnly />
<button
aria-disabled={pending}
formAction={formAction}
>
{pending && <LoadingSpinner />}
{alreadyFriends && 'Friends'}
{alreadySentRequest && 'Unsend Friend Request'}
{hasInboundRequest && 'Accept Friend Request'}
{(!alreadyFriends && !alreadySentRequest && !hasInboundRequest) && 'Send Friend Request'}
</button>
</>
)
}```
This used to work when I just passed the action in the button formAction, but I switched it to useFormState and now I'm getting an error in the action that formData.get is not a function. When I console log formData, it's the state. Do I have something mixed up here?
3 Replies
Palomino
I've started seeing the same - did you find a workaround?
MattOP
I don't actually remember what I changed specifically to fix it but this is the working version now:
"use client";
import { useFormState, useFormStatus } from "react-dom";
import {
acceptFriendRequestAction,
ignoreFriendRequestAction,
sendFriendRequestAction,
unfriendAction,
unsendFriendRequestAction,
} from "./actions";
import LoadingSpinner from "../utilities/LoadingSpinner";
import { useActionResponseToast } from "@/hooks/useActionResponseToast";
// TODO: this should all be one component with the parent form
export default function ClientFriendRequestButtonInternal({
targetUser,
alreadyFriends,
alreadySentRequest,
hasInboundRequest,
}: {
targetUser: string;
alreadyFriends: boolean;
alreadySentRequest: boolean;
hasInboundRequest: boolean;
}) {
let action = sendFriendRequestAction;
if (alreadyFriends) {
action = unfriendAction;
} else if (alreadySentRequest) {
action = unsendFriendRequestAction;
} else if (hasInboundRequest) {
action = acceptFriendRequestAction;
}
const { pending } = useFormStatus();
const [state, formAction] = useFormState(action, undefined);
useActionResponseToast(state);
return (
<div className="flex gap-2 flex-wrap justify-center">
<input type="hidden" name="targetUser" value={targetUser} readOnly />
<button
disabled={pending}
formAction={formAction}
className={`flex items-center gap-2 rounded-md ${
alreadyFriends || alreadySentRequest ? "bg-white ring-gray-300 hover:bg-gray-50" : "text-white bg-blue-500 hover:bg-blue-600"
} px-3 py-2 text-sm text-gray-900 shadow-sm ring-1 ring-inset `}
>
{alreadyFriends && "Remove Friend"}
{alreadySentRequest && "Unsend Friend Request"}
{hasInboundRequest && "Accept Friend Request"}
{!alreadyFriends && !alreadySentRequest && !hasInboundRequest && "Send Friend Request"}
{pending && <LoadingSpinner />}
</button>
{hasInboundRequest && <IgnoreRequestButton targetUser={targetUser} />}
</div>
);
}
function IgnoreRequestButton({ targetUser }: { targetUser: string }) {
const { pending } = useFormStatus();
const [state, formAction] = useFormState(ignoreFriendRequestAction, undefined);
useActionResponseToast(state);
return (
<>
<input type="hidden" name="targetUser" value={targetUser} readOnly />
<button
disabled={pending}
formAction={formAction}
className={`flex items-center gap-2 rounded-md bg-white ring-gray-300 hover:bg-gray-50 px-3 py-2 text-sm text-gray-900 shadow-sm ring-1 ring-inset `}
>
Ignore Request
{pending && <LoadingSpinner />}
</button>
</>
);
} @PalominoPalomino
Thanks bro - I'm thinking my issue is down to using Appwrite in my project because I can implement a form with a server action fine in a clean project