cf.completefrontend

Write the codeMedium

Write a form with useActionState that shows a pending button and the action's error

Write RenameForm, the default export: a form with a text box labelled Name (its name is name) and a Save button, whose submit runs as a form action through useActionState.

It takes rename(name), which returns a promise: it resolves when the server saved the name, and rejects with an Error whose message says why it didn't.

On submit, trim the name. If it's empty, show Enter a name. and don't call rename. Otherwise call rename. While it runs, the button says Saving… (with the single … character) and is disabled. When it works, show Saved as Sencha. (with the name) and leave the box empty. When rename rejects, show its message in an element with role="alert", and keep what was typed in the box. A later success clears the error.

<RenameForm rename={rename} />
 
// While it waits:  [ Sencha ] [Saving…]  (disabled)
// When it works:   [        ] [Save]   Saved as Sencha.
// When it fails:   [ Sencha ] [Save]   That name is taken.
Write this (App.jsx)
import { useActionState } from "react";
 
export default function RenameForm({ rename }) {
  // TODO: run the rename as an action with useActionState, and show
  // Saving…, the error, and the saved name.
  return (
    <form>
      <label>
        Name <input name="name" />
      </label>
      <button>Save</button>
    </form>
  );
}
The checks your code must pass
  • calls rename with the trimmed name
  • shows Saving… on a disabled button while it waits
  • shows the saved name and empties the box
  • an empty name shows Enter a name. and isn't sent
  • shows the rejection's message in an alert
  • keeps the typed name after an error
  • a later success clears the error

Try it in the editor

The answer

Write it yourself first. Then compare it with a reference solution and the checks it passes.

Checking your sign-in…