react-router-dom BrowserRouter not navigating to paths with more than one url parameter

微笑、不失礼 提交于 2019-12-11 16:46:20

问题


I am having an issue where I am not able to navigate to Routes with paths greater than 1 section like so when using react-router-dom@4.2.2: In addition, this is the Github link to the repo where I am having this issue.

https://github.com/ShawnCholeva/React-Typescript-Webpack4-Router

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
//All routes work if I use HashRouter here instead of BrowserRouter

class App extends Component {
    render() {
        return (
            <Router>
                <Switch>
                    <Route exact path='/' component={ Login }/> <--- Works
                    <Route exact path='/accountSetup/:guid?' component={ AccountSetup }/> 
                    ^-- Above works when just '/accountSetup' but fails when I do '/accountSetup/123'
                    <Route component={ NotFound } /> <--- Works
                </Switch>
            </Router>
        );
    }
}

So I noticed this is only working when I use HashRouter instead of BrowserRouter. So that led me to think it may be how I am serving the application via webpack-dev-server@3.1.1. So I saw that I had to add historyApiFallback property to my devServer properties object using webpack@4.2.0 like so:

devServer: {
    compress: true,
    port: 8080,
    historyApiFallback: true,
    contentBase: path.resolve(__dirname),
    publicPath: '/',
}

And then I run the application through a npm script in my package.json that looks like this:

"start": "webpack-dev-server --open --mode development"

So when I navigate to localhost:5000/accountSetup/123 I get the following error in the console:

I have also tried to serve this with the http-server-spa package and noticed the following log when navigating:

[OK] Serving static files from ./dist
[OK] Using the fallback file index.html
[OK] Listening on http://localhost:8080
----------------------------------------------
[OK] GET /accountSetup
[OK] GET /bundle.js
[OK] GET /accountSetup/123
[ER] GET /accountSetup/bundle.js

It seems like it is adding the prefix in the url of the last route parameter to the route loading bundle.js. So you can see when I navigated to accountSetup, it just referenced bundle.js because it the last segment in the url. But when I add multiple segments, it seems to append the prior segments from localhost to the last segment, to the path of bundle.js

EDIT:

Seems to be something in regards to BrowserRouter using dynamic routing vs HashRouter using static routing.

This is my full package.json and webpack.config.js files

package.json:

{
  "name": "react-webpack4-typescript-skeleton",
  "version": "1.0.0",
  "description": "React application using Webpack 4 and Typescript",
  "main": "index.tsx",
  "scripts": {
    "start": "webpack-dev-server --open --mode development",
    "prestart": "npm run test",
    "build:prod": "webpack --mode production --config webpack.config.js",
    "lint": "tslint 'src/**/*.{ts,tsx}'",
    "test": "jest",
    "pretest": "npm run lint",
    "build:docker": "docker-compose up --build -d"
  },
  "keywords": [
    "React",
    "Webpack 4",
    "Typescript"
  ],
  "author": "Shawn Choleva",
  "license": "MIT",
  "devDependencies": {
    "@types/jest": "^22.2.2",
    "@types/react": "^16.0.41",
    "@types/react-dom": "^16.0.4",
    "@types/react-redux": "^5.0.15",
    "@types/react-router-dom": "^4.2.5",
    "@types/redux": "^3.6.0",
    "@types/webpack": "^4.1.2",
    "@types/webpack-dev-server": "^2.9.4",
    "css-loader": "^0.28.11",
    "file-loader": "^1.1.11",
    "html-webpack-plugin": "^3.1.0",
    "jest": "^22.4.3",
    "less-loader": "^4.1.0",
    "style-loader": "^0.20.3",
    "ts-jest": "^22.4.2",
    "ts-loader": "^4.1.0",
    "tslint": "^5.9.1",
    "tslint-react": "^3.5.1",
    "typescript": "^2.7.2",
    "url-loader": "^1.0.1",
    "webpack": "^4.2.0",
    "webpack-cli": "^2.0.13",
    "webpack-dev-server": "^3.1.1"
  },
  "dependencies": {
    "less": "^3.0.1",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.2.2",
    "redux": "^3.7.2"
  },
  "jest": {
    "transform": {
      "^.+\\.tsx?$": "ts-jest"
    },
    "testRegex": "(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ]
  }
}

webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')

const config = {
  entry: './src/index.tsx',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: "style-loader"
          },
          {
            loader: "css-loader",
            options: {
              sourceMap: true,
              modules: true,
              localIdentName: '[local]___[hash:base64:5]'
             }
          },
          {
            loader: "less-loader"
          }
        ]
      },
      { 
        test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        use:'url-loader' 
      },
      { 
        test: /\.(png|jp(e*)g|svg)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 10000,
              name: 'images/[hash]-[name].[ext]',
            },
          }
        ]
      }
    ]
  },
  resolve: {
    extensions: [ '.ts', '.tsx', '.js' ]
  },
  plugins: [
    new HtmlWebpackPlugin({
        title: 'Application Name',
        template: path.join(__dirname, 'src/index.html')
    })
  ],
  devtool: 'inline-source-map',
  devServer: {
    compress: true,
    port: 8080,
    historyApiFallback: true,
    contentBase: path.resolve(__dirname),
    publicPath: '/',
  }
};

module.exports = config;

回答1:


I think I have found the issue. The publicPath was missing in your webpack configuration. Here is the updated output config:

output: {
   filename: 'bundle.js',
   path: path.resolve(__dirname, 'dist'),
   publicPath: '/' <-- ADDED THIS
  },



回答2:


Looks like you are trying to make a nested route. But in ReactRouter v4 which as you point out uses dynamic routing nested routes should be nested inside the component. Meaning in your AccountSetup render method you should add.

render(){
 //...
  <Route
    path={match.url + '/test'}
    component={Test}
  />
// ...
}

Read more about nested routes in the docs. Here is a live example.
If you do want to use static routes instead you can try this.



来源:https://stackoverflow.com/questions/49824582/react-router-dom-browserrouter-not-navigating-to-paths-with-more-than-one-url-pa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!