Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Routing doesn't work in react when typing url in browser

I have the following routes in the below class:

import { Router, Route } from 'react-router-dom';

class App extends React.Component {
    constructor(props) {
        super(props); 
    }

    render() {
        const { alert } = this.props;

        return (
            <Router history={history}>
                <div>                                  
                    <Route path="/login" component={LoginPage} />
                    <Route path="/administrate" component={AdministratePage} />     
                    <Route exact path='/' component={LoginPage} />   
                </div>
            </Router>
        );
    }
}

For http://localhost:12345/ the login component displays properly.

However when I'm typing in my browser http://localhost:12345/login or http://localhost:12345/administrate I'm getting 404's.

Typing 'http://localhost:12345/administrate' in the navigator gives a 404 but If I put :

this.props.history.push('/administrate');

in the render method of the Login component it redirects properly, showing the administrate component.

How come? I have no errors in my F12 console. Thank you very much.

My webpack.config.js:

   module.exports = {
   devServer: {
        historyApiFallback: true
    },
        context: __dirname,
        entry: "./index.js",
        output: {
            path: __dirname + "/dist",
            filename: "bundle.js" // naam van de file die je genereert. die bundle.js include je in je cshtml. Wordt voortdurend geupdate als je programmeert
        },
        resolve: {
            extensions: ['.js', '.jsx']
        },

        watch: true, // dan hoef je niet telkens npm run webpack te draaien, je ziet dan in je cmd 'webpack is watching the files'
        module: {
            rules: [
                {
                    test: /\.js$/,
                    exclude: /(node_modules)/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['babel-preset-env', 'babel-preset-react'], // deze heb je met npm geinstalleerd
                            plugins: ["transform-object-rest-spread"] // voor het gebruik van de spread operator
                        }
                    }
                },
                {
                    test: /\.css$/,
                    use: ['style-loader', 'css-loader']
                },
                {             // Werkt niet
                    test: /\.jsx$/, loader: 'babel-loader', exclude: '/node_modules/'
                }
            ]
        }
    };

index.js :

import { store } from './_helpers';
import { App } from './App';

render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
); 

History:

import { History } from './index'; // history 4.6.2
import { getConfirmation } from './DOMUtils';

export interface BrowserHistoryBuildOptions {
  basename?: string;
  forceRefresh?: boolean;
  getUserConfirmation?: typeof getConfirmation;
  keyLength?: number;
}

export default function createBrowserHistory(options?: BrowserHistoryBuildOptions): History;
like image 615
Ole EH Dufour Avatar asked Mar 08 '18 13:03

Ole EH Dufour


People also ask

How do I route a URL in React?

React Router is a standard library for routing in React. It enables the navigation among views of various components in a React Application, allows changing the browser URL, and keeps the UI in sync with the URL. Let us create a simple application to React to understand how the React Router works.

How do I add a browser to my React router?

To install React Router, all you have to do is run npm install react-router-dom@6 in your project terminal and then wait for the installation to complete. If you are using yarn then use this command: yarn add react-router-dom@6 .


2 Answers

Your server needs to deliver your app no matter what URL comes in, because your app, in the browser, is manipulating the URL. Our current server doesn't know how to handle the URL.

The Webpack Dev Server has an option to enable this. Open up package.json and add --history-api-fallback.

"start": "webpack-dev-server --inline --content-base . --history-api-fallback"

We also need to change our relative paths to absolute paths in index.html since the URLs will be at deep paths and the app, if it starts at a deep path, won't be able to find the files.

<!-- index.html -->
<!-- index.css -> /index.css -->
<link rel="stylesheet" href="/index.css">

<!-- bundle.js -> /bundle.js -->
<script src="/bundle.js"></script>

Configuring Your Server

As well you can also configure Webpack server inside webpack.config.js

 devServer: {
    historyApiFallback: true,
    contentBase: './',
    hot: true
  },

Try to use HashRouter from React Router Dom

import { HashRouter, Route } from "react-router-dom";



             <HashRouter>                          
                    <Route path="/login" component={LoginPage} />
                    <Route path="/administrate" component={AdministratePage} />     
                    <Route exact path='/' component={LoginPage} />  
             </HashRouter>
like image 149
Liam Avatar answered Oct 02 '22 16:10

Liam


Wrapping your App under BrowserRouter in the index.js is missing as stated here.

index.js

 import { store } from './_helpers';
    import { App } from './App';
    import { BrowserRouter } from "react-router-dom";

    render(
        <Provider store={store}>
          <BrowserRouter>
            <App />
          </BrowserRouter>
        </Provider>,
        document.getElementById('root')
    ); 

A fully working example should be like this.

App.js

import React, { Component } from 'react';
import { Switch, Route } from 'react-router-dom';
import Login from '../../Components/Login/Login';
import Signup from '../../Components/Signup/Signup';
import classes from './Home.css';
import HomePage from '../HomePage/HomePage';


class Home extends Component {

    render() {
    return (
        <div className={classes.Container}>
          <Switch>
            <Route path="/" exact component={HomePage} />
            <Route path="/login" component={Login} />
            <Route path="/signup" component={Signup} />
          </Switch>
        </div>

    );
  }
}
like image 39
Juan Camilo Giraldo Chaverra Avatar answered Oct 02 '22 17:10

Juan Camilo Giraldo Chaverra