nCardot
nCardot

Reputation: 6595

Why is e.preventDefault() making page refresh on submit?

I have a search handler method that performs a search (fetch from API) when a button is clicked. I didn't add e.preventDefault() to prevent the page from submiting as was suggested in a tutorial, but it didn't seem like the page was being refreshed when the search was performed. To be sure it wasn't being refreshed, I added e.preventDefault() to the search method and it actually caused the page to refresh and not display results -- the opposite of what was expected.

What caused this, and why didn't my page refresh on submit without e.preventDefault()?

Here is my search method with e.preventDefault(); added. It is bound in the constructor and passed as a prop to the search button (in another file).

searchJokes(limit = 15, e) {
    e.preventDefault();
    // If nothing entered, user gets "Please fill out this field" message due to "required" attribute on input element
    if (this.state.searchTerm !== '') {
      this.setState({
        isFetchingJokes: true,
        isSearch: true
      });

      fetch(
        `https://icanhazdadjoke.com/search?term=${
          this.state.searchTerm
        }&limit=${limit}`,
        {
          method: 'GET',
          headers: {
            Accept: 'application/json'
          }
      })
        .then(response => response.json())
        .then(json => {
          let jokes = json.results;
          this.setState({
            jokes,
            isFetchingJokes: false
          });
        });
    }
  }

Functional component containing form element (only the search button causes a call of the search method):

const RetrievalForm = props => (
  <form>
    <input
      type="text"
      placeholder="Enter search term..."
      onChange={props.onSearchInputChange}
      required
    />
    <button onClick={props.onSearch} disabled={props.isSearching}>Search</button>
    <button onClick={props.onRandomize} disabled={props.isSearching}>
      Randomize
    </button>
  </form>
);

Full code without e.preventDefault(); used: app.js retrieval-form.js

Edit: In the tutorial onSubmit was being used rather than onClick. Somehow onClick actually doesn't cause a page refresh, while onSubmit does. So I had no need to use e.preventDefault()

Edit 2: The onClick search doesn't cause a page refresh in Chrome, but it does in Firefox.

Upvotes: 0

Views: 3190

Answers (2)

MGS
MGS

Reputation: 456

The page will not refresh, because your fetch() block is making an asynchronous (Ajax) call. Asynchronous calls do not cause the page to refresh. If you want the the page to refresh after the asynchronous call is completed, add window.location.reload() in the then() block.

Upvotes: 1

wiesson
wiesson

Reputation: 6832

If your function or method searchJokes is being called on submit, then the first argument is your event. This applies to button and form events.

searchJokes(e) {
  e.preventDefault();
  // rest of onSubmit code
}

So in your case, if call the searchJoke event from a button click or form onSubmit event, then something like this might help

function searchJokes(ev, limit = 15) {
  ev.preventDefault();
  // ...
}

// event is passed to searchJokes as first argument, limit should be the second argument because it has a default value.
<button onClick={ev => searchJokes(ev, 30)}>Search Jokes</button>

Simple form example:

function MyForm() {
  function onFormSubmit(ev) {
    ev.preventDefault();
    const { name } = ev.currentTarget;
    console.log(name.value);
  }

  return (
    <form onSubmit={onFormSubmit}>
      <label htmlFor="name">Name</label>
      <input id="name" name="name" />
      <button type="submit">Submit form</button>
    </form>
  )
}

Upvotes: 0

Related Questions