How to Stop a React Form From Reloading the Page

A React form reloads the page on submit because the browser's default form action - a GET navigation to the same URL - fires before React's state update runs. One call to e.preventDefault() stops the navigation and lets React handle everything in JavaScript.

Fullstack Engineerfullstackreactforms

Why the page reloads

A <form> submit fires two things in order: the browser's default action (navigate to the action URL, or the current URL if none is set, encoding the inputs as a query string) and then any JavaScript onSubmit handler. The browser navigation happens first - it reloads the page, React re-mounts with fresh state, and the items or input values you set in the handler are gone.

This is why you see the URL flash a ?item=Milk query string right before the list empties: that's the browser doing a GET to the same route.

The fix: call e.preventDefault()

In your submit handler, call e.preventDefault() as the very first thing. It cancels the browser navigation so only your JavaScript runs.

import { useState } from 'react';

export default function App() {
  const [items, setItems] = useState<string[]>([]);
  const [text, setText] = useState('');

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault();                    // cancel the browser navigation
    setItems((prev) => [...prev, text]);   // update React state
    setText('');                           // clear the input
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="Add an item..."
      />
      <button type="submit">Add</button>
      <ul>
        {items.map((it, i) => <li key={i}>{it}</li>)}
      </ul>
    </form>
  );
}

The e argument is a React.FormEvent (a synthetic event wrapping the native browser event). preventDefault() exists on every event type - React.FormEvent, React.MouseEvent, React.KeyboardEvent - so the same pattern applies wherever you need to stop the browser's default behavior.

What the browser default actually does

Without preventDefault():

  1. Browser serializes the form fields: ?item=Milk
  2. Browser navigates to http://localhost:5173/?item=Milk
  3. React unmounts and re-mounts - all state resets to initial values
  4. Your setItems(...) call either never runs or runs against the now-reset state on the previous mount

With preventDefault(), step 1-3 never happen, and only your handler runs.

When preventDefault is not enough

Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.

Try it in a workspace →

What you'll practice

FAQ

Why does my React form reload the page on submit?

A <form> submit triggers the browser's default navigation action - it encodes the inputs as a query string and does a GET to the same URL, which reloads the page and resets all React state. Call e.preventDefault() in your onSubmit handler to cancel that navigation.

How do I stop a React form from refreshing the page?

In your onSubmit handler, accept the event as the first argument (typed React.FormEvent in TypeScript) and call e.preventDefault() before doing anything else. That cancels the browser default and leaves React in control.

Why does the URL get a query string when I submit a React form?

That's the browser's default form submission: it serializes every named input field into a query string and navigates to that URL. e.preventDefault() cancels it. If you still see the query string, the handler isn't attached or preventDefault isn't being reached.

Keep learning

Fix a React useState Stale-State BugFullstack projectFix a Blank React Dashboard (Failed Fetch)Fullstack projectFix the React Search That Won't Filter (useEffect Deps)Fullstack projectFullstack roadmapStep by step to hiredFullstack interview questionsSTAR answersAll Fullstack projectsProjects hub

Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.

Open the workspace →