React router not working after building the app

ghz 6months ago ⋅ 55 views

I am new to react and react-router. The app is created using create-react-app. I need to implement routing in my app with two main pages. I have tried many options and finally made it work with the following code.

This code works fine during development. But after building the app, its not working properly. The route to 404 page is only getting displayed. Please help me resolve this.

<Router history={browserHistory}>
  <Route component={Root}>
    <IndexRoute component={App} />
    <Route path="/" component={App} />
    <Route path="/sna/:country" component={SNA} />
    <Route path="*" component={FourOFour}/>
  </Route>
</Router>

I have used browserHistory to enable navigation on changing a dropdown using below code.

selectCountry(event){
    var value = event.target.value;
    browserHistory.push('/sna/' + value);
}

package.json

  {
  "name": "my-app",
  "version": "0.1.0",
  "homepage": "./",
  "private": true,
  "dependencies": {
    "bootstrap": "^3.3.7",
    "react": "^15.4.2",
    "react-addons-update": "^15.4.2",
    "react-bootstrap": "^0.30.8",
    "react-data-grid": "^2.0.24",
    "react-dom": "^15.4.2",
    "react-router": "^2.6.0"
  },
  "devDependencies": {
    "react-scripts": "0.9.5"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

Answers

The issue you're facing with React Router not working properly after building your app is likely due to the version mismatch between the React Router version (^2.6.0) you're using and the version of react-router-dom that is typically used with create-react-app projects.

Here’s how you can resolve this issue:

Step 1: Install react-router-dom

Since you are using create-react-app, which is typically used with react-router-dom instead of react-router, you should install react-router-dom and use it for routing in your application. react-router-dom is designed specifically for web applications using React.

npm install --save react-router-dom

Step 2: Update Your Router Configuration

Update your router configuration to use BrowserRouter from react-router-dom instead of Router with browserHistory.

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

<Router>
  <Switch>
    <Route exact path="/" component={App} />
    <Route path="/sna/:country" component={SNA} />
    <Route path="*" component={FourOFour}/>
  </Switch>
</Router>

Step 3: Modify Navigation to Use Link

Instead of manipulating the browser history directly, use Link component from react-router-dom for navigation.

import { Link } from 'react-router-dom';

<select onChange={this.selectCountry}>
  <option value="country1">Country 1</option>
  <option value="country2">Country 2</option>
</select>

selectCountry = (event) => {
  const value = event.target.value;
  this.props.history.push(`/sna/${value}`);
};

Step 4: Update package.json if Needed

Ensure that react-router-dom is listed as a dependency in your package.json and remove react-router if it's still listed.

"dependencies": {
  "react": "^15.4.2",
  "react-addons-update": "^15.4.2",
  "react-bootstrap": "^0.30.8",
  "react-data-grid": "^2.0.24",
  "react-dom": "^15.4.2",
  "react-router-dom": "^5.2.0"
},

Step 5: Test and Build

After making these changes, test your application locally to ensure routing works as expected. Once confirmed, run the build command again:

npm run build

Deploy the built files and verify that routing works correctly in the production environment.

Explanation

  • BrowserRouter vs Router: BrowserRouter is used for applications with browser history, and it handles routing using HTML5 history API. This is more appropriate for web applications, whereas Router can be used for more generic routing needs.

  • Link Component: Link from react-router-dom ensures that navigation is handled in a way that integrates with React Router's internal state management, which is crucial for proper navigation and rendering of components based on routes.

By following these steps and using react-router-dom instead of react-router, you align with the standard approach for routing in create-react-app projects, ensuring compatibility and correct functionality both during development and after building your application for production.