nico.fyi
Published on

How to close a dialog on success or render an error with Remix fetchers

Authors
  • avatar
    Name
    Nico Prananta
    Twitter
    @2co_p

Ryan Florence of Remix tweeted about how to close a dialog on success or to display some error messages after submitting a form with Remix's useFetcher.

export async function action({ request }: ActionFunctionArgs) {
  let formData = await request.formData();
  let status = formData.get('status');
  return status === 'success'
    ? { ok: true, error: null }
    : { ok: false, error: 'There was a problem' };
}

function Example() {
  let ref = useRef<HTMLDialogElement>(null);
  let fetcher = useFetcher<typeof action>();

  useEffect(() => {
    if (fetcher.state === 'idle' && fetcher.data?.ok) {
      ref.current?.close();
    }
  }, [fetcher]);

  return (
    <div>
      <button onClick={() => ref.current?.showModal()}>Open Dialog</button>
      <dialog ref={ref}>
        <fetcher.Form method="post">
          <p>{fetcher.state === 'idle' ? 'Make a choice' : 'working...'}</p>
          <button type="submit" name="status" value="success">
            Get Success
          </button>
          <button type="submit" name="status" value="error">
            Get Error
          </button>
          <p style={{ color: 'red' }}>
            {(fetcher.state === 'idle' && fetcher.data?.error) || <>&nbsp;</>}
          </p>
        </fetcher.Form>
      </dialog>
    </div>
  );
}

The code looks very simple because of the power of Remix's fetcher. ❤️


By the way, I have a book about Pull Requests Best Practices. Check it out!