URL包含多个路径时,React Router无法正常工作

时间:2019-02-20 12:15:46

标签: reactjs webpack react-router

我正在使用 webpack-dev-server 进行开发,并对路由器做出同样的反应。这是我的wepack配置。

const webpack = require('webpack');
const path = require('path');
const common = require('./common.config.js')
const merge  = require('webpack-merge')

const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin')

module.exports = merge(common, {
    devtool: 'source-map',
    mode:'development',
    module: {
        rules: [
           {
                test: /\.(sa|sc|c)ss$/,
            use: [
                       {
                  // Adds CSS to the DOM by injecting a `<style>` tag
                  loader: 'style-loader'
                       },
                       {
                          // Interprets `@import` and `url()` like `import/require()` and will resolve them
                          loader: 'css-loader'
                   },
                   {
                          // Loader for webpack to process CSS with PostCSS
                          loader: 'postcss-loader',
                          options: {
                          plugins: function () {
                                return [
                                require('autoprefixer')
                                ];
                                   }
                          }
                       },
               {
                  // Loads a SASS/SCSS file and compiles it to CSS
                  loader: 'sass-loader'
               }
                 ]
           }
        ]
    },
    devServer:{
       contentBase: path.join(__dirname, '../dist'),
       port: 3000,
       proxy:{
          '/api': 'http://127.0.0.1:5000',
       },
       historyApiFallback:true,
       overlay: true,
       stats: 'normal'
    },
    watchOptions: {
       ignored: /node_modules/
    },

    plugins: [
    new CleanWebpackPlugin(['../dist'], { exclude:['sw.js']}),
        new HtmlWebpackPlugin({
            title: 'Script App - Dev',
            filename: '../dist/index.html',
        template:'index_template.html'
        }),
    new MiniCssExtractPlugin({
            filename: 'bundled_styles.css'
        }),
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()    
    ],
});

这是我的应用程序的入口点(在其中定义了路线)

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import {BrowserRouter, Route, Switch} from 'react-router-dom'

import configureStore from './store/configureStore';

import FirstComponent from './FirstComponent';
import SecondComponent from './SecondComponent';
import App from './App';

const store = configureStore();

ReactDOM.render(
    <Provider store={store}>
        <BrowserRouter>
            <App>
               <Switch>
                   <Route path="/first/:a_code" component={FirstComponent} />
                   <Route path="/second" component={SecondComponent} />
               </Switch>
            </App>
        </BrowserRouter>
    </Provider>,

    document.getElementById('root')
);

我正在使用react-router v4wepack v4.29

我的问题:当我使用history道具从代码中推送路由时,一切正常,但是当我使用该路由刷新浏览器时,一切一片空白。 仅在具有多条路径的路由上会观察到此行为/first/:param)。

我尝试过的操作:我从一些SO帖子中了解到,我必须将webpack配置中的historyApiFallback属性设置为true,但确实做到了仍然没有帮助。 this github issue中的评论之一说,如果Webpack配置中某些historyApiFallback配置可用,则proxy将无法正常工作。

我不想删除这些proxy配置,因为我正在对运行在不同端口上的另一台服务器进行api调用。

有人可以帮我吗?拜托!

2 个答案:

答案 0 :(得分:0)

我遇到了类似的情况,我使用render:func解决了,该方法避免了在位置匹配时重新安装组件。

所以我的路线看起来像这样

<Route
  path="/first/:a_code"
  render={props => 
    <FirstComponent {...props}/>
  }
/>

然后在我的组件中获得匹配的参数

const first_component = (props) => {
  return (
    <div>
      {props.match.params.a_code}
    </div>
  )
}
在网址“ / first / something”中的

,我可以刷新浏览器并仍然获得所需的参数,并且没有任何错误或空白页。而且我不认为这是配置问题,因为到目前为止我还没有在该项目中弹出webpack配置。

答案 1 :(得分:0)

我实际上错过了一个webpack配置。我必须添加一个output配置,并将publicPath设置为/。即

output:{
  publicPath: '/'
}

我还在publicPath配置中添加了devServer。即

devServer:{
  ...
  publicPath:'/'
}