我花了兩天多的時間尋找解決我的問題,我真的需要你的幫助。React路由器v4(找不到頁面)服務器端渲染
當我將我的示例部署到服務器併到達頁面,如site.com/home和重新加載此頁面後,我得到錯誤:未找到請求的URL/在此服務器上找不到URL。
在React Router文檔中,我發現爲了防止出現這個問題,我需要使用SSR,但每次嘗試使用這些代碼和其他代碼來解決此問題時,我都遇到了同樣的錯誤。
例子的代碼:https://reacttraining.com/react-router/
目錄地圖:
modules
- App.js
node_modules
public
- bundle.js
- index.css
- index.html
index.js
package.json
package-lock.json
server.bundle.js
server.js
webpack.config.js
webpack.server.config.js
App.js
import React from 'react'
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom'
const App =() => (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<hr/>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/topics" component={Topics}/>
</div>
</Router>
)
const Home =() => (
<div>
<h2>Home</h2>
</div>
)
const About =() => (
<div>
<h2>About</h2>
</div>
)
const Topics = ({ match }) => (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/rendering`}>
Rendering with React
</Link>
</li>
<li>
<Link to={`${match.url}/components`}>
Components
</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
<Route path={`${match.url}/:topicId`} component={Topic}/>
<Route exact path={match.url} render={() => (
<h3>Please select a topic.</h3>
)}/>
</div>
)
const Topic = ({ match }) => (
<div>
<h3>{match.params.topicId}</h3>
</div>
)
export default App
index.html的 - 與容器的id = 「應用程序」 和腳本SRC簡單的網頁= 「bundle.js」
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from './modules/App'
ReactDOM.render((
<BrowserRouter>
<App/>
</BrowserRouter>
), document.getElementById('app'))
的package.json
{
"name": "",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
"start:dev": "webpack-dev-server --inline --content-base public/ --history-api-fallback",
"start:prod": "npm run build && node server.bundle.js",
"build:client": "webpack",
"build:server": "webpack --config webpack.server.config.js",
"build": "npm run build:client && npm run build:server"
},
"author": "",
"license": "ISC",
"dependencies": {
"compression": "^1.6.1",
"express": "^4.13.4",
"http": "0.0.0",
"if-env": "^1.0.0",
"react": "^0.14.7",
"react-dom": "^0.14.7",
"react-router": "^2.0.0",
"react-router-dom": "^4.1.2"
},
"devDependencies": {
"babel-core": "^6.5.1",
"babel-loader": "^6.2.2",
"babel-preset-es2015": "^6.5.0",
"babel-preset-react": "^6.5.0",
"http-server": "^0.8.5",
"webpack": "^1.12.13",
"webpack-dev-server": "^1.14.1"
}
}
server.js
import { createServer } from 'http'
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { StaticRouter } from 'react-router'
import App from './modules/App'
createServer((req, res) => {
const context = {}
const html = ReactDOMServer.renderToString(
<StaticRouter
location={req.url}
context={context}
>
<App/>
</StaticRouter>
)
if (context.url) {
res.writeHead(301, {
Location: context.url
})
res.end()
} else {
res.write(`
<!doctype html>
<div id="app">${html}</div>
`)
res.end()
}
}).listen(3000)
webpack.config.js
var webpack = require('webpack')
module.exports = {
entry: './index.js',
output: {
path: 'public',
filename: 'bundle.js',
publicPath: '/'
},
plugins: process.env.NODE_ENV === 'production' ? [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
] : [],
module: {
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' }
]
}
}
webpack.server.config.js
var fs = require('fs')
var path = require('path')
module.exports = {
entry: path.resolve(__dirname, 'server.js'),
output: {
filename: 'server.bundle.js'
},
target: 'node',
// keep node_module paths out of the bundle
externals: fs.readdirSync(path.resolve(__dirname, 'node_modules')).concat([
'react-dom/server', 'react/addons',
]).reduce(function (ext, mod) {
ext[mod] = 'commonjs ' + mod
return ext
}, {}),
node: {
__filename: true,
__dirname: true
},
module: {
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' }
]
}
}
在本地主機上一切正常。 我將非常感謝任何幫助。
你的'App'是BrowserRouter的組件。所以在你的serverjs中,你實際上是在StaticRouter中渲染BrowserRouter。嘗試並分開保存路由和路由器。檢查了這一點https://github.com/ReactTraining/react-router/tree/master/packages/react-router-config – Fawaz