Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-router 2.0 browserHistory doesn't work when refreshing

Below codes report 404 not found when refreshing on page http://localhost/about. But if browserHistory is changed to hashHistory, it works fine.

Here are my js file.

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, IndexRoute, Link, IndexLink, browserHistory, hashHistory } from 'react-router';
import $ from 'jquery';

class App extends Component {
  render() {
    return (
      <div>
        <h1>APP!</h1>
        <Link to="/about">/about</Link>
        {this.props.children}
      </div>
    )
  }
}

class About extends React.Component {
  render() {
    return (
      <div>
        <h2>About 33</h2>
      </div>
    )
  }
}

var routes = (
    <Router history={hashHistory}>
        <Route path="/" component={App} />
        <Route path="/about" component={About} />
        <Route path="/wealth" component={WealthExpectation} />
    </Router>
)

$(document).ready(function() {ReactDOM.render(routes, document.getElementById("hello"))});

And the html file.

<!doctype html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Hello React</title>
        <script type="text/javascript" src="/static/js/jquery-1.12.2.min.js"></script>
        <script type="text/javascript" src="/static/js/script.js"></script>
        <!-- build:css -->
          <link rel="stylesheet" type="text/css" href="/static/bower_modules/c3/c3.min.css">
        <!-- endbuild -->
    </head>
    <body>
        <div id="hello">a</div>
        <div id="world"></div>
    </body>
</html>

I've read the questions on react-router v2.0 browserHistory not working and React-router urls don't work when refreshing or writting manually. For the first one, I've already set the path to absolute path, but still not working. For the second one, I tried to import express but failed ('Uncaught TypeError: Cannot read property 'prototype' of undefined').

like image 448
Cuero Avatar asked Apr 26 '16 06:04

Cuero


People also ask

How do I use Browserhistory in react Router?

React Router uses the history package, which builds on the browser history API to provide an interface to which we can use easily in React apps. location - (object) The current location. May have the following properties: pathname - (string) The path of the URL.

Does react Router refresh the page?

react-router-dom allows us to navigate through different pages on our app with/without refreshing the entire component. By default, BrowserRouter in react-router-dom will not refresh the entire page.

How do I refresh a page using react dom Router?

import React from 'react'; function App() { function refreshPage() { window. location. reload(false); } return ( <div> <button onClick={refreshPage}>Click to reload!

How do you refresh the page without reload in react?

How do you refresh a page without reloading in react? Method 1: Refresh a Page Using JavaScript window. location. reload(false); This method takes an optional parameter which by default is set to false.


2 Answers

To expand on Phi Nguyen's answer the reason hashHistory works and browserHistory fails is because hashHistory is sort of a 'hack' or workaround to allow your app to manipulate the URL without the browser noticing and sending a GET request to your server. Essentially everything after the Hash is ignored.

browserHistory is generally preferred because it looks better but you no longer get the hash workaround and you need other means of preventing your browser from trying to send requests to your server. IF you are using webpack there is a simple way to essentially make all requests fallback to a single request. For example:

GET to http://localhost:8080/ AND a GET to http://localhost:8080/about would both fallback to http://localhost:8080/ and react-router would deal with the /about. (this is the reason you are able to navigate to /about fine, but if you refresh you get a 404 error, you're sending a GET to /about which doesn't exist on your server)

To do this you need to implement a webpack feature called history api fallback. There's two ways of doing that.

From the react-router docs / tutorial you can setup your start script to look like this:

"start": "webpack-dev-server --inline --content-base . --history-api-fallback"

Where the --history-api-fallback is the important piece for anyone with this error.

OR you can change your webpack.config.js file to look handle this on your dev server.

  devServer: {
    historyApiFallback: true,
    ...other stuff..
  },
like image 181
jmancherje Avatar answered Oct 20 '22 16:10

jmancherje


An alternative, simple and low-cost approach is to make Apache map any request to your React app. For example: http://localhost/about goes internally thru http://localhost/[my-own-html-file.html]

For example, if our React app starts at index.html, you need to create a .htaccess file on your React app and insert the following code:

# Map all non-existing URLs to be processed by index.html,
# so any URL that doesn't point to a JS file, CSS file, etc etc...
# goes through my React app.

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^ index.html [L]
</IfModule>

BTW, this HTACCESS code was adapted from Drupal 8: https://github.com/drupal/drupal/blob/8.2.x/.htaccess

like image 41
Ignacio Segura Avatar answered Oct 20 '22 17:10

Ignacio Segura