ReactJS with React Router - strange routing behaviour on Chrome
Asked Answered
S

1

3

This is a bit weird and I would like to get to the bottom of it.

I have a page where users type in their email address and click a button and then I show "you're signed up!" message - simple.

For that, I have two routes. The main route and the "signed-up" route.

  <Route name="app" path="/" handler={Main}>
    <Route name="signed-up" path="signed-up" handler={SignedUp} />
    <DefaultRoute handler={Signup} />
  </Route>

On the first page, when users type in the email address and click the button, I fire POST AJAX to save the email address on my backend DB (using Axios package) and when it's completed, I go to the "signed-up" route.

  handleSubmit() {
    var router = this.context.router;
    var email  = this.refs.email.getDOMNode().value;
    this.refs.email.getDOMNode().value = '';

    helpers.postSignupEmail(email).then((response) => {
      // then display the signed up page
      router.transitionTo("signed-up");
    });
  }

Now when I first type in the URL of my page

http://localhost:1338

Browsers (Chrome, FireFox, Safari), all seem to change the URL to

http://localhost:1338/#/

Fair enough. In FireFox, I type in an email and click the submit button, it all works well and takes me to

http://localhost:1338/#/signed-up

Now on Chrome, however, when I click on the submit, it doesn't change the route. In fact, on developer console, I see an error.

enter image description here

First, why was the "post" request cancelled? Second, when this happens, Chrome is un-responsive. So I refresh the page, then I get Chrome's "navy screen death"..

enter image description here

Now, funnily enough, if I change the initial URL to

http://localhost:1338/?#/

(inserting the question mark in front of hash), then things work fine on Chrome. So, it makes me wonder that it's something to do with my route paths or parameters.

Any ideas?

Shun answered 8/7, 2015 at 23:43 Comment(1)
Have you tried just using the HistoryLocation API? Instead of hash urls.Coherence
D
15

Just faced this problem a few hours ago.

So you have something like that in your component (es6 syntax):

render() {
    return (
        <form onSubmit={ this.submit.bind(this) }>
            { /* inputs stuff here */ }
        </form>
    );
}

submit() {
    // Ajax request here
}

The problem is that Chrome try to send a get request, and appends a ? to your current URL, because you don't have any action="/formsubmit" in your form tag and it thinks it is a method="get", by default. So Chrome take the current URL (for example myapp.com/#/) and tries to send form at myapp.com/?#/, which is a new URL.

To prevent that, simply add a preventDefault when you submit your form

submit(e) {
    e.preventDefault()
    // Ajax request here
}
Disserve answered 14/9, 2015 at 17:49 Comment(3)
I would click the up-arrow 10 times if I could. I had run into this scenario with Angular 2 RC6 and spent days chasing my tail, tracing through the router, trying to figure out what was going on. Then I saw your explanation here -- Fireworks and churchbells! I had no idea clicking on a non-submit button could cause a submit. In the end, to fix my issue I just needed to change <button> to <span>. Thank you for sharing your insight!Oldenburg
@Oldenburg I encourage you to use the <button> tag as it is more sementically correct and leads to a cleaner code: for a form submit, you should always use the submit event, + preventDefault if needed.Disserve
@KeitlG thanks for that input, however in my case I'm not wanting to do a form submit, just linking to another form. The fact that a submit was happening without any intention to do so was what threw me for a loop.Oldenburg

© 2022 - 2024 — McMap. All rights reserved.