【react-router-dom】4.xになって辛い。。理解したい人のためのreact-router-dom

【react-router】ハマった「browserHistoryをhistoryに渡すと」「Failed to load resource: the server responded with a status of 404 (Not Found)」

【react-router】ハマって抜けなかったエラー「browserHistoryをhistoryに渡すと」Failed to load resource: the server responded with a status of 404 (Not Found)
かれこれ2時間ぐらい戦っていました。

Failed to load resource: the server responded with a status of 404 (Not Found)
Failed to load resource: the server responded with a status of 404 (Not Found)

自分のコード

[javascript]
import React, { Component } from 'react'
import { Router, Route, Link, IndexRoute, hashHistory, browserHistory } from 'react-router'
class App extends Component {
render() {
console.log(browserHistory)
return (
<Router history={browserHistory}>
<Route path='/' component={Home} />
<Route path='address' component={Address} />
</Router>
)
}
}
const Home = () =>

<h1>Hello from Home!</h1>

const Address = () =>

<h1>We are located at 555 Jackson St.</h1>

export default App
[/javascript]

これの何がいけないんですかって。

事象

・RouterにbrowserHistroyを渡すとaddressをurl更新で叩くとエラーになる
・hashHistoryを渡すとページ遷移できる

答え

https://github.com/reactjs/react-router-tutorial/tree/master/lessons/10-clean-urls
ここです。

どうやらwebpackの設定とindex.htmlでbundle.jsのパスに問題があったようです。

下の記述は「connect-history-api-fallback」というwebpackで実行しなくてはならないものでそのdocumentに理由が書いてありました。

Single Page Applications (SPA) typically only utilise one index file that is accessible by web browsers: usually index.html. Navigation in the application is then commonly handled using JavaScript with the help of the HTML5 History API. This results in issues when the user hits the refresh button or is directly accessing a page other than the landing page, e.g. /help or /help/online as the web server bypasses the index file to locate the file at this location. As your application is a SPA, the web server will fail trying to retrieve the file and return a 404 - Not Found message to the user.

This tiny middleware addresses some of the issues. Specifically, it will change the requested location to the index you specify (default being /index.html) whenever there is a request which fulfills the following criteria:

The request is a GET request
which accepts text/html,
is not a direct file request, i.e. the requested path does not contain a . (DOT) character and
does not match a pattern provided in options.rewrites (see options below)

Webサーバーがインデックスファイルをバイパスしてこの場所にファイルを配置するためです。アプリケーションがSPAであるため、
Webサーバーはファイルを取得しようとして失敗し、404 - Not Foundメッセージをユーザーに返します。

自分の場合 package.jsonのnpm scriptを下記のように変更

[javascript]
"scripts": {
"start": "webpack-dev-server",
"build": "webpack"
},
[/javascript]

ここのserver立ち上げるstartの記述を

[javascript]
"scripts": {
"start": "webpack-dev-server --inline --content-base . --history-api-fallback",
"build": "webpack"
},
[/javascript]

に変更。

htmlのバンドルファイルのパスを

[html]
<body>

<h1>React router3.x</h1>

<main></main>
<script src="./bundle.js"></script>
</body>
[/html]

以下に変更

[html]
<body>

<h1>React router3.x</h1>

<main></main>
<script src="/bundle.js"></script>
</body>
[/html]

サーバープロセスkillして
もう一回
npm start
してください。。

参照
https://stackoverflow.com/questions/36857147/react-router-2-0-browserhistory-doesnt-work-when-refreshing
https://github.com/reactjs/react-router-tutorial/tree/master/lessons/10-clean-urls