Next.js Discord

Discord Forum

Setting FormAction result as query param?

Answered
Great Kiskadee posted this in #help-forum
Open in Discord
Avatar
Great KiskadeeOP
Hello All,

I am interested in setting the result of a server action as a query string on success so that the result state can be linked to other users.

'use client';
import { useFormStatus, useFormState } from 'react-dom';
import { addCreatorAction } from './add-creator.action';
import { useEffect, useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';

export function AddCreatorForm() {
  const [creatorName, setCreatorName] = useState('');
  const [searchState, formAction] = useFormState(
    addCreatorAction,
    null
  );
  // const router = useRouter();
  // useEffect(() => {
  //   searchState?.found && router.push(`?name=${searchState.result.name}`, {scroll: false});
  // }, [searchState]);
  return (
    <>
      <form action={formAction}>
        <label htmlFor="name">Name:</label>
        <input
          type="text"
          id="name"
          name="name"
          value={creatorName}
          onChange={(e) => setCreatorName(e.target.value)}
        />
        <button type="submit">Submit</button>
      </form>
      {searchState?.found && (
        <div>
          <h2>{searchState.result.name}</h2>
          <h3>{searchState.result.id}</h3>
        </div>
      )}
      {(searchState?.found === false && searchState.similar.length > 0) && (
        <div>
          <h1>Did you mean:</h1>
          <ul>
            {searchState.similar.map((creator) => (
              <li>{creator.name}</li>
            ))}
          </ul>
        </div>
      )}
    </>
  );
}

In this code, the server action works as expected, however to push the results into the url I would have to use a side effect which I have my reservations about. Is there something about the server action/form action API that I'm missing that includes this functionality?

I know that the Link component has an href prop that does something similar to what I'm looking for.
Answered by Shy Albatross
server action can return a redirect() with the URL you want but giving that link to others would give them an empty form, unless you fill the form client side from the data in URL
View full answer

4 Replies

Avatar
Great KiskadeeOP
Ended up doing this:
 useEffect(() => {
    if (searchState) {
      const searchParams = new URLSearchParams();
      if (searchState.found) {
        searchParams.set('sr', JSON.stringify(searchState.result));
      }
      if (searchState.similar?.length > 0) {
        searchParams.set(
          'ss',
          encodeURIComponent(JSON.stringify(searchState.similar))
        );
      }
      router.push(`?${searchParams.toString()}`);
    }
  }, [searchState, router]);
Avatar
Great KiskadeeOP
Nevermind, it's sloppy. I would appreciate any pointers.
Avatar
Shy Albatross
server action can return a redirect() with the URL you want but giving that link to others would give them an empty form, unless you fill the form client side from the data in URL
Answer
Avatar
Great KiskadeeOP
I really appreciate that!
The empty form is actually ideal because it is a search form, I want to store the results as a way to cache results of a query into a URL!