All skills
sergiodxa avatar

/frontend-react-router-best-practices

@9da9532

React Router performance and architecture patterns. Use when writing loaders, actions, forms, routes, or working with React Router data fetching. Triggers on tasks involving React Router routes, data loading, form handling, or route organization.

Use this Skill: https://skilld.dev/gh/sergiodxa/agent-skills/frontend-react-router-best-practices

This session only. Nothing lands on disk.

rulesform-reset-on-success.md

≈904 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Reset Form on Success

Reset uncontrolled form inputs after a successful action submission using a ref and effect.

Why

  • Uncontrolled inputs don't clear automatically after submission
  • React doesn't re-mount inputs when staying on the same route
  • Users expect forms to clear after successful submission
  • Prevents accidental re-submission of the same data

The Problem

When using uncontrolled inputs (no value prop), the input values persist after submission:

// Form stays filled after submission - bad UX
export default function Component() {
  return (
    <Form method="post">
      <input name="title" />
      <button type="submit">Create</button>
    </Form>
  );
}

Solution: Reset with Ref and Effect

With Form

import { Form, useActionData, useNavigation } from "react-router";
import { useEffect, useRef } from "react";

export default function Component() {
  let formRef = useRef<HTMLFormElement>(null);
  let navigation = useNavigation();
  let actionData = useActionData<typeof action>();

  useEffect(
    function resetFormOnSuccess() {
      if (navigation.state === "idle" && actionData?.ok) {
        formRef.current?.reset();
      }
    },
    [navigation.state, actionData],
  );

  return (
    <Form method="post" ref={formRef}>
      <input name="title" />
      <button type="submit">Create</button>
    </Form>
  );
}

With useFetcher

import { useFetcher } from "react-router";
import { useEffect, useRef } from "react";

function CreateItemForm() {
  let formRef = useRef<HTMLFormElement>(null);
  let fetcher = useFetcher<typeof action>();

  useEffect(
    function resetFormOnSuccess() {
      if (fetcher.state === "idle" && fetcher.data?.ok) {
        formRef.current?.reset();
      }
    },
    [fetcher.state, fetcher.data],
  );

  return (
    <fetcher.Form method="post" ref={formRef}>
      <input name="title" />
      <button type="submit">Create</button>
    </fetcher.Form>
  );
}

Action Response Pattern

Return a success indicator from your action:

export async function action({ request }: Route.ActionArgs) {
  let formData = await request.formData();

  try {
    await createItem(formData);
    return data({ ok: true });
  } catch (error) {
    return data({ ok: false, error: "Failed to create" }, { status: 400 });
  }
}

Or use a status literal:

return data({ status: "success" as const });

// In component
if (fetcher.state === "idle" && fetcher.data?.status === "success") {
  formRef.current?.reset();
}

Alternative: Key-Based Reset

For simpler cases, use a key to force React to remount the form:

function CreateItemForm() {
  let [key, setKey] = useState(0);
  let fetcher = useFetcher<typeof action>();

  useEffect(() => {
    if (fetcher.state === "idle" && fetcher.data?.ok) {
      setKey((k) => k + 1); // Remounts entire form
    }
  }, [fetcher.state, fetcher.data]);

  return (
    <fetcher.Form method="post" key={key}>
      <input name="title" />
      <button type="submit">Create</button>
    </fetcher.Form>
  );
}

Note: This remounts the entire form, which may reset focus. Use the ref approach for better UX.

Rules

  1. Use formRef.current?.reset() to clear uncontrolled inputs
  2. Check both state === "idle" and success indicator before resetting
  3. Return a success indicator (ok: true or status: "success") from actions
  4. Prefer ref-based reset over key-based remounting
  5. Don't reset on error - user may want to correct their input

Source: SKILL.md on GitHub

2 warnings16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides a comprehensive set of developer guidelines and best practices for building React Router applications. It emphasizes performance, type safety, and security measures like input validation (Zod), safe redirects, and CSRF protection (Sec-Fetch). No malicious code, obfuscation, or data exfiltration patterns were detected.

  • Socket16d

    1 alert: gptSecurity

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    56/56 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 9da9532. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 8 months ago

README badge

README badge for sergiodxa/agent-skills/frontend-react-router-best-practices