1

On top of my app, I have the following main router

export class App extends React.Component {

    render() {
        return (
            <div>
                <Router>
                    <Switch>
                        <Route exact path={Paths.login} component={LoginForm} />
                        <Route path={Paths.dashboard} component={Dashboard} />
                    </Switch>
                </Router>
            </div>
        )
    }

}

Further in dashboard, I have a side menu with links

export class Dashboard extends React.Component<RouteComponentProps> {

    constructor(props: RouteComponentProps) {
        super(props)
        this.handleLogoutClick = this.handleLogoutClick.bind(this)
    }

    handleLogoutClick() {
        UserRepository.logout()
        this.props.history.push(Paths.login)
    }

    render() {
        return UserRepository.isLoggedIn() ? (
            <div>
                <BrowserRouter>
                    <div id="menu">
                        <div className="title">Dashbaord</div>
                        <Nav className="flex-column" defaultActiveKey>
                            <Link to={`${this.props.match.path}/users`}>Users</Link>
                            <Nav.Link onClick={this.handleLogoutClick}>Logout</Nav.Link>
                        </Nav>
                    </div>
                    <div id="content">

                        <Switch>
                            <Route path={`${this.props.match.path}/users`} component={Users} />
                        </Switch>
                    </div>
                </BrowserRouter>

            </div>

        ) : Paths.redirectToLogin()
    }

}

When I go to dashbaord and click users link, it works, but if I refresh the page with same url, it shows blank page. Any solution on how I can go directly to child route?

I am very new to react js, kind a learning now. I found debugging this routing thing very difficult, you don't get any error or clue what went wrong!

webpack config file

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

const distDir = path.resolve(__dirname, 'dist')

module.exports = {
    entry: [
        "./src/index.tsx"
    ],
    mode: 'development',
    output: {
        filename: "main.js",
        path: distDir
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'babel-loader',
                exclude: /node_module/
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader'
                ]
            }
        ]
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js']
    },
    plugins: [
        new HtmlWebpackPlugin(
            {
                title: 'Dashboard',
                template: 'index.html'
            }
        ),
        new MiniCssExtractPlugin()
    ],
    devServer: {
        contentBase: distDir,
        historyApiFallback: {
            index: 'index.html'
        },
        hot: true
    },
    externals: {
        "react": "React",
        "react-dom": "ReactDOM"
    }
}
mallaudin
  • 4,744
  • 3
  • 36
  • 68

1 Answers1

0

Just tried a fresh install of react-router-dom with this code and looks to be working for me. My guess is either the strings are off or there is additional library or functionality that is prevent the page to load.

If you are running this in local with yarn start then the routes should handle loading.

Possible Error:

If you are using this in a production environment, building the react app, and the loading just the build (html & js), then you would still need to configure your nginx or http server to point all routes to the single index.html file, otherwise your http server might just look for a folder that doesn't exist and show a blank page on a page refresh.

Here's the code that's working for me:

File: App.tsx


import React from 'react';
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Dashboard from './Dashboard'

class App extends React.Component {
  render () {
    return (
      <div>
        <BrowserRouter>
          <Switch>
            <Route exact path={'/login'} render={() => <h1>Login</h1>} />
            <Route path={'/dashboard'} component={Dashboard} />
          </Switch>
        </BrowserRouter>
      </div>
    )
  }
}

export default App;

File: Dashboard.tsx

import React from 'react';
import { Route, Switch, Link } from "react-router-dom";

class Dashboard extends React.Component {
  render () {
    return (
      <div>
          <h1>Dashboard</h1>
          <ul>
            <li><Link to="/dashboard/users">Users</Link></li>
            <li><Link to="/dashboard/account">Account</Link></li>
            <li><Link to="/login">Login</Link></li>
          </ul>
          <Switch>
            <Route path={'/dashboard/users'} render={() => <h2>Users</h2>} />
            <Route path={'/dashboard/account'} render={() => <h2>Account</h2>} />
          </Switch>
      </div>
    )
  }
}

export default Dashboard;
codingwithmanny
  • 1,126
  • 8
  • 20
  • yup, forgot to mention. yes, i have configured the server, I am using webpack local server. example on react router page also works, I modified that online to try , but it doesn't work in my project. – mallaudin Jun 28 '20 at 17:38
  • So local works with page refreshes, or is it just production that has the issues? What kind of server are you using, nginx, apache, other, and what are your settings? – codingwithmanny Jun 28 '20 at 17:40
  • i am running it locally. it is just a demo project. i am using webpack dev server to load app in browser. – mallaudin Jun 28 '20 at 17:42
  • Got it and did you setup the webpack configuration yourself, or did you use the scaffolded `create-react-app` ? – codingwithmanny Jun 28 '20 at 17:45
  • i did it myself. – mallaudin Jun 28 '20 at 17:54
  • ` devServer: { contentBase: distDir, historyApiFallback: { index: 'index.html' } }` – mallaudin Jun 28 '20 at 17:54
  • * otherwise your http server might just look for a folder that doesn't exist and show a blank page on a page refresh.* this makes sense. – mallaudin Jun 28 '20 at 18:12
  • Then it's definitely got to be related with the webpack configurations.It's a bit more complex, but not impossible. I would recommend posting your configuration file, to see how it's working. Otherwise, if you're hoping to save time, I would just do `npx create-react-app --template typescript your-project-folder` and port your code to that, or use it as a reference to look at how they implemented webpack, but last time I checked, it had quite a few files to it. – codingwithmanny Jun 28 '20 at 18:28
  • sure, posted my webpack config – mallaudin Jun 28 '20 at 18:41
  • Webpack is definitely finicky, but I think this has now become a question about webpack. Here are some links I found, which may help: https://stackoverflow.com/questions/44805562/how-to-configure-webpack-dev-server-with-react-router-dom-v4 https://github.com/upasanaa/react-router-basic-example https://www.freecodecamp.org/news/learn-webpack-for-react-a36d4cac5060/ – codingwithmanny Jun 29 '20 at 06:04
  • 1
    https://stackoverflow.com/questions/56573363/react-router-v4-nested-routes-not-work-with-webpack-dev-server this one helped me. thanks – mallaudin Jun 29 '20 at 08:17