admin管理员组

文章数量:1026373

I'm working on a React app and i'm trying to figure out a better way to redirect to 404 page not found when user hits a wrong path.
Basically my application has a navbar with three main routes (Home, Content, Permissions) and a default redirect to render a route that displays 404 page not found:

<Switch>
  <Route path="/home" ponent={Home} />
  <Route path="/content" ponent={Content} />
  <Route path="/permissions" ponent={Permissions} />
  <Route path="/not-found" ponent={PageNotFound} />
  <Redirect to="/not-found" />
</Switch>

My problem is with the /Permissions route because this one has many subroutes to display multiple configuration pages and i need to fetchData with a hook, so if the user goes to a wrong path it needs to wait for data fetching before being redirected to page not found:

const Permissions = () => {
  const {isFetchingData} = usePermissionsData();

  if(isFetchingData) {
    return <Loading />;
  } 

  return (
    <div className={styles.permissions} >
      <div className={styles.leftMenu} >
        <LeftMenu />
      </div>
      <div className={styles.content} >
        <Switch>
          <Route path="/permissions" ponent={PermissionsWele}
          <Route path="/permissions/users" ponent={UsersPermissions}
          <Route path="/permissions/content" ponent={ContentPermissions}
          <Route path="/permissions/dashboard" ponent={DashboardPermissions}
          <Redirect to="/not-found" />
        </Switch>
      </div>
    </div>
  );
}

So my question is if it exists a better way to redirect the user to a page not found without needing to wait for the data fetching? (something that i consider is a waste of proccesing).
Any suggestion is wele!

I'm working on a React app and i'm trying to figure out a better way to redirect to 404 page not found when user hits a wrong path.
Basically my application has a navbar with three main routes (Home, Content, Permissions) and a default redirect to render a route that displays 404 page not found:

<Switch>
  <Route path="/home" ponent={Home} />
  <Route path="/content" ponent={Content} />
  <Route path="/permissions" ponent={Permissions} />
  <Route path="/not-found" ponent={PageNotFound} />
  <Redirect to="/not-found" />
</Switch>

My problem is with the /Permissions route because this one has many subroutes to display multiple configuration pages and i need to fetchData with a hook, so if the user goes to a wrong path it needs to wait for data fetching before being redirected to page not found:

const Permissions = () => {
  const {isFetchingData} = usePermissionsData();

  if(isFetchingData) {
    return <Loading />;
  } 

  return (
    <div className={styles.permissions} >
      <div className={styles.leftMenu} >
        <LeftMenu />
      </div>
      <div className={styles.content} >
        <Switch>
          <Route path="/permissions" ponent={PermissionsWele}
          <Route path="/permissions/users" ponent={UsersPermissions}
          <Route path="/permissions/content" ponent={ContentPermissions}
          <Route path="/permissions/dashboard" ponent={DashboardPermissions}
          <Redirect to="/not-found" />
        </Switch>
      </div>
    </div>
  );
}

So my question is if it exists a better way to redirect the user to a page not found without needing to wait for the data fetching? (something that i consider is a waste of proccesing).
Any suggestion is wele!

Share Improve this question asked Aug 16, 2021 at 6:54 Abraham ArreolaAbraham Arreola 3474 silver badges15 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

"A better way" can be subjective, but to help with the objective issue of needing to match a route before checking permissions then I suggest inverting control. By this I mean you should create a custom Route ponent that will be matched first then check the permissions. It's not clear if your code snippet is a simplified version, but I assume the hook probably also determines if a user has permission to access the current route/resource. If there is an additional check for this then you can conditionally render a Route with the current props or you can render a Redirect to "bounce" the user off the route since they are missing required permission(s).

Example:

const PermissionRoute = props => {
  const {isFetchingData} = usePermissionsData();

  if(isFetchingData) {
    return <Loading />;
  }

  return <Route {...props} />;
};

Permissions

const Permissions = () => {
  return (
    <div className={styles.permissions} >
      <div className={styles.leftMenu} >
        <LeftMenu />
      </div>
      <div className={styles.content} >
        <Switch>
          <PermissionRoute path="/permissions/users" ponent={UsersPermissions} />
          <PermissionRoute path="/permissions/content" ponent={ContentPermissions} />
          <PermissionRoute path="/permissions/dashboard" ponent={DashboardPermissions} />
          <PermissionRoute path="/permissions" ponent={PermissionsWele} />
          <Redirect to="/not-found" />
        </Switch>
      </div>
    </div>
  );
}

Main Routing

<Switch>
  <Route path="/home" ponent={Home} />
  <Route path="/content" ponent={Content} />
  <Route path="/permissions" ponent={Permissions} />
  <Route path="/not-found" ponent={PageNotFound} />
  <Redirect to="/not-found" />
</Switch>

React router is priority based, The top lines/top routes have more priority than others, you can just add a route with a normal react page with no path attribute, Example:

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

import Main from './Main'; // Main ponent
import NotFound from './NotFound'; // Create a not found ponent

const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" ponent={Main} />
      <Route ponent={NotFound} /> // this must be placed atlast.
    </Switch>
  </Router>
);

render(<App />, document.getElementById('root'));

I'm working on a React app and i'm trying to figure out a better way to redirect to 404 page not found when user hits a wrong path.
Basically my application has a navbar with three main routes (Home, Content, Permissions) and a default redirect to render a route that displays 404 page not found:

<Switch>
  <Route path="/home" ponent={Home} />
  <Route path="/content" ponent={Content} />
  <Route path="/permissions" ponent={Permissions} />
  <Route path="/not-found" ponent={PageNotFound} />
  <Redirect to="/not-found" />
</Switch>

My problem is with the /Permissions route because this one has many subroutes to display multiple configuration pages and i need to fetchData with a hook, so if the user goes to a wrong path it needs to wait for data fetching before being redirected to page not found:

const Permissions = () => {
  const {isFetchingData} = usePermissionsData();

  if(isFetchingData) {
    return <Loading />;
  } 

  return (
    <div className={styles.permissions} >
      <div className={styles.leftMenu} >
        <LeftMenu />
      </div>
      <div className={styles.content} >
        <Switch>
          <Route path="/permissions" ponent={PermissionsWele}
          <Route path="/permissions/users" ponent={UsersPermissions}
          <Route path="/permissions/content" ponent={ContentPermissions}
          <Route path="/permissions/dashboard" ponent={DashboardPermissions}
          <Redirect to="/not-found" />
        </Switch>
      </div>
    </div>
  );
}

So my question is if it exists a better way to redirect the user to a page not found without needing to wait for the data fetching? (something that i consider is a waste of proccesing).
Any suggestion is wele!

I'm working on a React app and i'm trying to figure out a better way to redirect to 404 page not found when user hits a wrong path.
Basically my application has a navbar with three main routes (Home, Content, Permissions) and a default redirect to render a route that displays 404 page not found:

<Switch>
  <Route path="/home" ponent={Home} />
  <Route path="/content" ponent={Content} />
  <Route path="/permissions" ponent={Permissions} />
  <Route path="/not-found" ponent={PageNotFound} />
  <Redirect to="/not-found" />
</Switch>

My problem is with the /Permissions route because this one has many subroutes to display multiple configuration pages and i need to fetchData with a hook, so if the user goes to a wrong path it needs to wait for data fetching before being redirected to page not found:

const Permissions = () => {
  const {isFetchingData} = usePermissionsData();

  if(isFetchingData) {
    return <Loading />;
  } 

  return (
    <div className={styles.permissions} >
      <div className={styles.leftMenu} >
        <LeftMenu />
      </div>
      <div className={styles.content} >
        <Switch>
          <Route path="/permissions" ponent={PermissionsWele}
          <Route path="/permissions/users" ponent={UsersPermissions}
          <Route path="/permissions/content" ponent={ContentPermissions}
          <Route path="/permissions/dashboard" ponent={DashboardPermissions}
          <Redirect to="/not-found" />
        </Switch>
      </div>
    </div>
  );
}

So my question is if it exists a better way to redirect the user to a page not found without needing to wait for the data fetching? (something that i consider is a waste of proccesing).
Any suggestion is wele!

Share Improve this question asked Aug 16, 2021 at 6:54 Abraham ArreolaAbraham Arreola 3474 silver badges15 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

"A better way" can be subjective, but to help with the objective issue of needing to match a route before checking permissions then I suggest inverting control. By this I mean you should create a custom Route ponent that will be matched first then check the permissions. It's not clear if your code snippet is a simplified version, but I assume the hook probably also determines if a user has permission to access the current route/resource. If there is an additional check for this then you can conditionally render a Route with the current props or you can render a Redirect to "bounce" the user off the route since they are missing required permission(s).

Example:

const PermissionRoute = props => {
  const {isFetchingData} = usePermissionsData();

  if(isFetchingData) {
    return <Loading />;
  }

  return <Route {...props} />;
};

Permissions

const Permissions = () => {
  return (
    <div className={styles.permissions} >
      <div className={styles.leftMenu} >
        <LeftMenu />
      </div>
      <div className={styles.content} >
        <Switch>
          <PermissionRoute path="/permissions/users" ponent={UsersPermissions} />
          <PermissionRoute path="/permissions/content" ponent={ContentPermissions} />
          <PermissionRoute path="/permissions/dashboard" ponent={DashboardPermissions} />
          <PermissionRoute path="/permissions" ponent={PermissionsWele} />
          <Redirect to="/not-found" />
        </Switch>
      </div>
    </div>
  );
}

Main Routing

<Switch>
  <Route path="/home" ponent={Home} />
  <Route path="/content" ponent={Content} />
  <Route path="/permissions" ponent={Permissions} />
  <Route path="/not-found" ponent={PageNotFound} />
  <Redirect to="/not-found" />
</Switch>

React router is priority based, The top lines/top routes have more priority than others, you can just add a route with a normal react page with no path attribute, Example:

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

import Main from './Main'; // Main ponent
import NotFound from './NotFound'; // Create a not found ponent

const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" ponent={Main} />
      <Route ponent={NotFound} /> // this must be placed atlast.
    </Switch>
  </Router>
);

render(<App />, document.getElementById('root'));

本文标签: javascriptBetter way to handle 404 page not found in a React appStack Overflow