ISR & Revalidation — Series 3

Preview — 3 of 10 questions

What are the three values useActionState returns?

javascript
'use client';
import { useActionState } from 'react';
import { submit } from './actions';

function Form() {
  const [state, formAction, isPending] = useActionState(submit, { error: null });
  return (
    <form action={formAction}>
      <input name="email" />
      <button disabled={isPending}>Save</button>
      {state.error && <p>{state.error}</p>}
    </form>
  );
}
A[data, error, reset]
B[state, formAction, isPending] — the current state (initially the second argument, then whatever the action returns), a wrapped action to pass to <form action> (or a button's formAction), and a pending boolean while the action is in flight
C[value, setValue, loading] — it is just useState with a spinner
D[formAction, state] — only two values

The post appears on /blog, /blog/[slug], and / (a latest posts widget). Data was fetched with fetch(url, { next: { tags: ['posts'] } }). What is the most precise invalidation?

javascript
'use server';
import { revalidatePath, revalidateTag } from 'next/cache';

export async function publishPost(id: string) {
  await db.post.update({ where: { id }, data: { published: true } });
  // which invalidation?
}
ArevalidatePath('/blog') only — the other routes will catch up eventually on their own
BNothing is needed; Server Actions always refresh every route
CrevalidateTag('posts') — it invalidates every cached fetch (and unstable_cache entry) tagged 'posts' regardless of which route used it, so all three pages refresh; revalidatePath would require naming each route explicitly
DrevalidatePath('/', 'layout') which recursively rebuilds the entire site

How does the returned object reach the UI?

javascript
'use server';
export async function checkUsername(_prev: unknown, formData: FormData) {
  const name = String(formData.get('username'));
  const taken = await db.user.findFirst({ where: { name } });
  return taken ? { ok: false, msg: 'Taken' } : { ok: true, msg: 'Available' };
}
AIt becomes the new state from useActionState — the client wires the action through useActionState, and React updates state with the action's return value after it resolves, re-rendering the component
BIt is written to localStorage automatically
CIt is thrown and must be caught in an error.tsx boundary
DServer Actions cannot return values — only redirect or revalidate

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.