简体   繁体   中英

Page reload if react-router-dom doesn't match any route

We are working in a project which is written in dotnet with Razor views (Pure Backend stack). Our plan to move every view to React using react-router-dom to handle routing in the client and server.

What we have in mind is to move page by page not to do a big bang because the project is already in production.

When I setup react-router-dom looks like every page is handled on the client and there is no full page reload if the route is not within the routes that Router handles.

Client Router

import { Router } from 'react-router-dom'
import { createBrowserHistory, History } from 'history'

const history: History = createBrowserHistory({ basename: baseUrl })

<Router history={history}>
  ...(routes and page layout)
</Router>

Server Router

<StaticRouter
 basename={basename}
 context={routerContext}
 location={params.location.path}
>
   ...(routes and page layout)
</StaticRouter>

Is there any way to make the router work in this way:

  • If the route is within the ones handled by react-router-dom , then do client side transition
  • If the router is not within the ones handled by react-router-dom (which means it's still handled by dotnet backend), make a full page reload.

Let me know if you need more information. Thank you in advance.

You need to add a NoMatch component for * route at the end of your Router

<Route component={NoMatch} />

and define your NoMatch component like below

function NoMatch() {
    window.location.reload();
    return null;
}

Also, your routes should be within a <Switch> because otherwise NoMatch will execute as well as your route and this will cause and endless loop. See documentation for more details: https://reacttraining.com/react-router/web/api/Switch

Luckily we have history prop to help, which provides an action param that can indicate whether the user navigated from another route or started on the current route directly.

So this is how I solved the reload-loop issue:

/**
 * Handles Legacy/SSR pages, reloads the page when the location changes
 *
 * @param {object} props Props
 * @param {object} props.location Location object
 * @param {object} props.history  History object
 */
const LegacyRoute = ( { location, history } ) => {
    useEffect( () => {
        // Reload the page if the location change ( and not on first load )
        if ( history.action === 'PUSH' ) {
            window.location.reload();
        }

        return () => {
            // Reload the page if we navigate away to another route
            window.location.reload();
        }
    }, [ location.pathname ] );

    return null;
}

Then you define the route as:

<Route component={ LegacyRoute } />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM