Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12111

How to delay the form submission using server actions with Nextjs 14?

$
0
0

I have the following Form component which receives the input fields as a children prop:

  return (<form action={dispatch} className="w-full flex" autoComplete="off"><div className={`${fieldSpacing} ${maxWidthClass} w-full`}>        {React.Children.map(children, (child) => {          if (React.isValidElement(child)) {            const isCustomComponent = typeof child.type !== "string";            const childProps = isCustomComponent              ? {                  ...child.props,                  errors: errors[child.props.name],                  formState,                }              : {                  ...child.props,                };            return React.cloneElement(child, childProps);          }          return child;        })}        {notification && <Notification {...notification} />}</div></form>  );

That currently works well but I need to delay the submission to make some animations in the form before the data is sent to the server. Then I've modified the code to:

  const handleAction = (event: React.FormEvent<HTMLFormElement>) => {    event.preventDefault();    const formData = new FormData(event.currentTarget);    dispatch(formData);  };  return (<form      //action={dispatch}      onSubmit={handleAction}      className="w-full flex"      autoComplete="off"><div className={`${fieldSpacing} ${maxWidthClass} w-full`}>        {React.Children.map(children, (child) => {          if (React.isValidElement(child)) {            const isCustomComponent = typeof child.type !== "string";            const childProps = isCustomComponent              ? {                  ...child.props,                  errors: errors[child.props.name],                  formState,                }              : {                  ...child.props,                };            return React.cloneElement(child, childProps);          }          return child;        })}        {notification && <Notification {...notification} />}</div></form>  );

This also works, sending the data to the server but the problem is that I cannot automatically get the pending state (from useFormStatus) on my submit button component anymore (it works using the action in the first version of the code).

This is my button component (submit):

const Button: React.FC<Props> = ({ title, bgColor, href, ...buttonProps }) => {  const { pending } = useFormStatus();  const bgColorClass =    bgColor === "purple"      ? "bg-purple-900 hover:bg-purple-950 border-purple-950 disabled:bg-purple-950 disabled:border-purple-950"      : "bg-indigo-800 hover:bg-indigo-900 border-indigo-900 disabled:bg-indigo-900 disabled:border-indigo-900";  const isSubmitLoading = buttonProps.type === "submit" && pending;  // Text animation variants  const textVariants = {    initial: { y: 0, opacity: 1 },    hidden: { y: -20, opacity: 0 },  };  // Spinner animation variants  const spinnerVariants = {    initial: { y: 20, opacity: 0 },    visible: { y: 0, opacity: 1 },  };  const ButtonContent = (<>      {!isSubmitLoading && (<motion.div          initial="initial"          animate={isSubmitLoading ? "hidden" : "initial"}          variants={textVariants}          transition={{ duration: 0.2 }}>          {title}</motion.div>      )}      {isSubmitLoading && (<motion.div          initial="initial"          animate={isSubmitLoading ? "visible" : "hidden"}          exit={{ opacity: 0 }}          variants={spinnerVariants}          transition={{ duration: 0.2 }}><LiaSpinnerSolid className="animate-spin text-xl" /></motion.div>      )}</>  );  return (<div className="w-full">      {href ? (<Link          href={href}          className={`inline-flex items-center justify-center border rounded-md py-2 px-4 text-sm font-bold text-gray-100 shadow-sm transition-all duration-200 w-full uppercase ${bgColorClass}`}>          {ButtonContent}</Link>      ) : (<button          {...buttonProps}          className={`inline-flex items-center justify-center border rounded-md py-2 px-4 text-sm font-bold text-gray-100 shadow-sm transition-all duration-200 w-full uppercase disabled:cursor-not-allowed ${bgColorClass}`}          disabled={buttonProps.disabled || pending}>          {ButtonContent}</button>      )}</div>  );};

How can I fix it? Is the only option to create a global state for this? I'd like to get the this to work using the pending state if possible.

Thank you!


Viewing all articles
Browse latest Browse all 12111

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>