Home > Software design >  Mac M1 Attempted import error: 'Switch' is not exported from 'react-router'
Mac M1 Attempted import error: 'Switch' is not exported from 'react-router'

Time:12-08

On Windows, npm run start works fine, but npm run start on m1 gives an error.
Why are you doing this?

Failed to compile
./node_modules/react-router-config/esm/react-router-config.js
Attempted import error: 'Switch' is not exported from 'react-router'.
This error occurred during the build time and cannot be dismissed.

"react-router-dom": "^5.3.0", "react-scripts": "^4.0.1",

This is the app.js code.

import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import routes from "./Routes";
import {renderRoutes} from "react-router-config";


import theme from './theme';
import {ThemeProvider} from "styled-components";

export default function App() {
    return (
                    <BrowserRouter>
                        {renderRoutes(routes)}
                    </BrowserRouter>
    );
};
``

CodePudding user response:

If you accidentally updated react-router-dom to version 6 it no longer exports a Switch component. It was replaced by a Routes component that must directly wrap/render the Route components.

  1. Swap the Switch for the Routes component.

    import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
    ...
    
    function App() {
      return (
        <Router>
          <Routes>
            <Route path="/" element={<Home/>} />
          </Routes>
        </Router>
      );
    }
    

    Follow the Upgrading from v5 to migrate your project from v5 to v6 across your app as there were quite a few breaking component API changes.

  2. Revert back to react-router-dom v5.

CodePudding user response:

The problem seems to be that of the version of react-router-dom The code that you have written seems to be compatible with version 5 and the package that you have installed is likely version 6. Please check.

In version 6

  1. Switch is replaced with Routes
  2. Default behavior of routes is to match exact routes.
  3. component={Loader} must now be written as element={<Loader />}
  4. useHistory is replaced with useNavigate.
  5. The order in which we list the routes does not matter. the algorithm now selects the best possible match.

Steps to upgrade to v6

npm uninstall react-router-dom
npm install react-router-dom@6

Then follow the below-mentioned tutorial to make the changes in your code. It should start working fine.

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

function App() {
  return (
    <Router basename={process.env.PUBLIC_URL}>
      <Routes>
        <Route path="/" element={<Home/>} />
        <Route path="/dashboard" element={<Dashboard/>} />
        <Route path="/*" element={<NotFoundPage/>} />
      </Routes>
    </Router>
  );
}

Also, it is a good practice to make use of basename={process.env.PUBLIC_URL} to set the public url through .env file.

The other way to solve this

The other way would be to revert back to version 5 but I would highly encourage you to upgrade to version 6 since it offers a smaller bundle size, better route selection, improved coding style and a lot more intuitive way of coding the nested routes.

References

  1. Upgrading to v6 Guide
  2. Upgrading to v6 Tutorial
  • Related