Design a multi-step wizard form pattern in React

shared state, step validation, and resilient navigation. A great answer uses one form instance with per-step Zod schemas, a context stepper, and localStorage persistence. Red flag: isolated forms per step that lose data on navigation.
What's really being asked
This question probes whether you can separate orchestration from presentation in a complex React form. The interviewer cares about state cohesion, validation timing, and UX resilience when users move non-linearly through a flow.
A GOOD ANSWER COVERS four things in order. First, a single form instance at the wizard root using React Hook Form with a defaultValues object that holds the entire shape, so every step writes into the same field registry. Second, per-step Zod schema slices that are composed into a master schema; the nextStep handler triggers schema.safeParse on only the current step's fields before incrementing the index, preventing progress on invalid input. Third, a lightweight context or custom hook that exposes the current step index, a goToStep function guarded by validation state, and derived metadata like isFirstStep or isLastStep so the shell controls navigation. Fourth, persistence via localStorage or sessionStorage using a useEffect or a library like Mantine Hooks to hydrate defaultValues on mount and debounce saves on change, preventing data loss on accidental refresh.
The mistakes people make
Treating each step as an independent form with its own useState and submit handler, which forces you to stitch data together at the end and breaks back-navigation validation. Another red flag is validating the entire schema on every step change, which surfaces errors for untouched future fields. A third is using URL query params for step index without guarding direct access to later steps, letting users skip required validation.
What usually comes next
How would you handle conditional steps that appear based on earlier answers? The answer should mention dynamic step arrays and unregistering fields when branches change. How do you prevent double submission? Mention disabling the submit button via formState.isSubmitting. What if a step has async validation like checking username availability? Describe using the resolver with async refinements or manual trigger calls.
A concrete example
Imagine a checkout wizard with shipping, payment, and review steps. The root component wraps the form in FormProvider and renders the active step by array index. The shipping step uses Zod to enforce address fields; on click next, the resolver validates only those fields. If the user refreshes at step two, a useLocalStorage hook repopulates defaultValues from cache. The review step reads all cached data from the single form state and submits once.
Interview question
Which pattern best prevents data loss and supports accurate per-step validation when users move non-linearly through a React wizard?
- a.Use a single root form but validate the entire Zod schema on every step change, relying solely on React state without persistence.
- b.Store the step index in URL query parameters and validate the full Zod master schema on every Next or Back click.
- c.Maintain a single root form instance, validate only the current step's Zod slice before advancing, and hydrate defaultValues from localStorage on mount.Correct
- d.Give each step its own form instance and useState, merging collected data only after the final step submission.
Why? this is the answer
A single root form with per-step Zod slices ensures only touched fields are validated before navigation, while localStorage hydration prevents data loss on refresh. Option A is tempting because it correctly centralizes the form, but validating the entire schema prematurely surfaces errors for untouched future fields and skipping persistence leaves users vulnerable to data loss.
Just read this? Test yourself on what you have been reading.
Read the original → blog.logrocket.com
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on react — each one lists the topics its interview covers.
See open roles