Jonson
Jonson

Reputation: 45

How to upgrade react-router-dom to v6

I Upgrade all Switch elements to Routes and components change to element
How to change what's left to v6

Routes.js

import React, { lazy, Suspense } from 'react';
import { HashRouter as Routes, Route, Router } from 'react-router-dom';
import Loading from './components/Loading';
import { ProtectedRoute, WithLayoutRoute } from './routers';
import { AdminLayout, PublicLayout } from './layouts';
const MovieList = lazy(() => import('./pages/Admin/MovieList'));
const MoviePage = lazy(() => import('./pages/Public/MoviePage'));

const Routess = () => {
  return (
    
    <Suspense fallback={<Loading />}>
      
        <Routes>
          <Route exact path="/login" element={<Login/>} />
          <Route exact path="/register" element={<Register/>} />
          <WithLayoutRoute exact path="/movie/:id" layout={PublicLayout} layoutProps={{ withFooter: false }} element={<MoviePage/>} />
          <ProtectedRoute exact path="/admin/movies" layout={AdminLayout} element={<MovieList/>} />
          <Route path="*" element={() => '404 NOT FOUND'} />
          
        </Routes>
    </Suspense>
  );
};

export default Routess;

Ok, i upgraded my Routes.js as you said, but i dont update WithLayoutRoute and ProtectedRoute. How change it? I don't know how to change it: ProtectedRoute.js:

import...
const ProtectedRoute = ({ layout: Layout, component: Component, isAuthenticated, ...rest }) => (
  <Route
    {...rest}
    render={props =>
      isAuthenticated ? (
        <Layout>
          <Component {...props} />
        </Layout>
      ) : (
        <Navigate to={{ pathname: '/', state: { from: props.location } }} />
      )
    }
  />
);

ProtectedRoute.propTypes = {
  isAuthenticated: PropTypes.bool
};
ProtectedRoute.defaultProps = {
  isAuthenticated: false
};
const mapStateToProps = state => ({
  isAuthenticated: state.authState.isAuthenticated
});
export default connect(mapStateToProps)(ProtectedRoute);

Upvotes: 3

Views: 863

Answers (1)

Drew Reese
Drew Reese

Reputation: 202836

From what you've provided what remains is fixing the custom route components. react-router-dom@6 no longer supports custom route components and only Route and React.Fragment components are valid children of the Routes component. You should see invariant warnings/errors with the above code if you have actually run it.

Convert the custom route components to layout components that render and Outlet each for nested Route components to be rendered into.

Example:

const WithLayoutRoute = ({ layout: Layout, layoutProps}) => {
  ...
  return (
    <Layout {...layoutProps}>
      <Outlet />
    </Layout>
  );
};

const ProtectedRoute = ({ layout: Layout }) => {
  const location = useLocation();
  ...
  return (
    <Layout>
      {auth
         ? <Outlet />
         : <Navigate to="/login" replace state={{ from: location }} />
      }
    </Layout>
  );
};

Wrap the routes you in new layout routes.

const Routess = () => {
  return (
    <Suspense fallback={<Loading />}>
      <Routes>
        <Route path="/login" element={<Login/>} />
        <Route path="/register" element={<Register/>} />

        <Route
          element={(
            <WithLayoutRoute
              layout={PublicLayout}
              layoutProps={{ withFooter: false }}
            />
          )}
        >
          <Route path="/movie/:id" element={<MoviePage/>} />
        </Route>

        <Route element={<ProtectedRoute layout={AdminLayout} />}>
          <Route path="/admin/movies" element={<MovieList/>} />
        </Route>

        <Route path="*" element={'404 NOT FOUND'} />
      </Routes>
    </Suspense>
  );
};

See Layout Routes for more detail.

Upvotes: 2

Related Questions