【问题标题】:React Single Page app with browserHistory possible?可以用 browserHistory 反应单页应用程序吗?
【发布时间】:2017-05-24 02:27:48
【问题描述】:

我一直在使用来自 react-router 的 hashHistory 构建一个反应单页应用程序,并且一切正常,直到我决定删除 URL 中的尾随代码,如下所示:#/?_k=ncbx6v。

我遇到的推荐解决方案是转换到 browserHistory,但我注意到所有示例和解决方案都需要使用 webpack-dev-server 并将 history-api-fallback 设置为 true。我尝试了这种方法并且它有效(通过localhost),但是曾经有效的独立 bundle.js 文件 + index.html 不再有效。

当我运行 webpack 并打开 html 文件时,我在控制台中收到此错误: Warning: [react-router] Location "/Users/mike/project/index.html" did not match any routes

我不熟悉问题背后的机制,但我很好奇是否有我不熟悉的解决方案。

这是我的 webpack 文件:

const {resolve} = require('path')

module.exports = () => {
  return {
    context: resolve('src'),
    entry: './app',
    output: {
      path: resolve('public'),
      filename: 'bundle.js',
      publicPath: '/public/'
    },
    resolve: {
      extensions: ['.js', '.jsx', '.json']
    },
    stats: {
      colors: true,
      reasons: true,
      chunks: false
    },
    module: {
      rules: [
        {enforce: 'pre', test: /\.jsx?$/, loader: 'eslint-loader', exclude: [/node_modules/]},
        {test: /\.jsx?$/,loader: 'babel-loader', include: /src/, exclude: /node_modules/
        },
        {test: /\.json$/, loader: 'json-loader'},
        {test: /(\.css)$/, loaders: ['style-loader', 'css-loader']},
        {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader"},
        {test: /\.(woff|woff2)$/, loader: "url-loader?prefix=font/&limit=5000"},
        {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=application/octet-stream"},
        {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=image/svg+xml"}
      ]
    }
  }
}

这是我的 app.js:

'use strict'
import React from 'react'
import ReactDOM from 'react-dom'
import Layout from './components/common/Layout'
import { Router, Route, IndexRoute, browserHistory } from 'react-router'
import configureStore from './store/configureStore'
import { Provider } from 'react-redux'

const store = configureStore()

class App extends React.Component {
  render () {
    return (
      <Provider store={store}>
        <Router history={browserHistory}>
          <Route path='/' component={Layout}></Route>
        </Router>
      </Provider>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

【问题讨论】:

    标签: reactjs webpack react-router webpack-dev-server


    【解决方案1】:

    为了使用浏览器历史记录,您需要一个可以处理所有可能路由的路由的后端。如果您不打算拥有可以支持路由的后端(例如,您将提供静态文件),您应该坚持使用哈希历史记录。

    浏览器历史如何工作的基本解释是它查看当前 URL 的pathname 并尝试将其与已知路由进行匹配。在您包含的错误中,您的pathname 是/Users/mike/project/index.html。这意味着为了让 React Router 匹配该 URL,您必须将 &lt;Route&gt; 的 path(或一系列嵌套的 &lt;Route&gt;s)定义为 /Users/mike/project/index.html。

    <Route path='Users/mike/project/index.html' component={App} />
    

    哈希历史记录适用于静态文件,因为它只是在 pathname 之后附加一个哈希符号,并根据之后的内容确定路由。

    如果您的问题只是您不喜欢查询键(?_k=jkadjlkd),您可以指定在create your history instance 时不应包含该键。这些 URL 仍将包含 #,但不再附有密钥“垃圾”。

    import { Router, useRouterHistory } from 'react-router'
    import { createHashHistory } from 'history'
    
    const appHistory = useRouterHistory(createHashHistory)({ queryKey: false })
    <Router history={appHistory} />
    

    【讨论】:

    • 非常感谢!我还想向其他用户指出,这只适用于 history@2.1.2 或更低版本。我最初安装了最新版本的历史记录,但最终呈现了一个空白页面。
    • 您之前使用的是哪个版本的history?查看更新日志github.com/mjackson/history/blob/v3.2.1/CHANGES.md#300-0 似乎在v3 中hashHistory 默认不应该包含查询键。 v4 不起作用,因为它被重写以用于即将发布的 v4 的 React Router。
    • 确实是默认安装的v4。我刚刚测试了 v3 并删除了querykey: false,但我在控制台中遇到了一个新错误:bundle.js:578 Uncaught Error: You have provided a history object created with history v3.x. This version of React Router is not compatible with v3 history objects. Please use history v2.x instead. 似乎我应该坚持使用 2?注意我正在使用 react-router@2.0.0
    • 如果你愿意,你可以坚持使用 v2,但是 React Router 的 v3 与 v2 兼容(它只是从 v1 中删除了不推荐使用的代码),所以使用 RR v3 应该轻松升级。
    • 知道了,我会检查一下。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 2013-10-21
    • 2018-04-20
    • 1970-01-01
    • 2011-02-11
    • 2018-07-01
    • 1970-01-01
    相关资源
    最近更新 更多