Реагируйте: как структурировать маршруты для администратора, пользователя и общественности - PullRequest
1 голос
/ 16 апреля 2020

Я пытаюсь выяснить, как структурировать маршрутизатор для использования различных маршрутов для администратора, пользователя и публикации c.

Я видел этот пост и ответ, описывающий ключ плащ - но я не смог разобраться в этом.

Я видел эту кодовую песочницу , которая выглядит логичной для меня, но у меня возникают проблемы с ее включением.

У меня есть файл констант, в котором я и определяю маршруты как:

export const NEWBLOG = '/admin/newblog';
export const VIEWBLOG = '/viewblog';

Я импортирую это в свое приложение. js, а затем хочу определить различные константы для администратора, пользователя и Publi c следующим образом:

import * as ROUTES from '../../util/constants/Routes';
import NewBlog from '../../components/blog/admin/New';

// admin routes
const Admin = ({ match }) => (
  <React.Fragment>
    <Route path={`${match.path}/${ROUTES.NEWBLOG}`} component={NewBlog} />
    <Route path={`${match.path}/2`} render={() => <h2>test</h2>} />
  </React.Fragment>
);

// authenticated user routes
const Other = ({ match }) => (
  <React.Fragment>
    <Switch>
      <Route path={`${match.path}/2`} render={() => <h2>one</h2>} />
      <Route path={`${match.path}/2`} render={() => <h2>two</h2>} />
    </Switch>
  </React.Fragment>
);

// public routes
const Public = ({ match }) => (
  <React.Fragment>
    <Switch>
      <Route path={`${match.path}/2`} render={() => <h2>one</h2>} />
      <Route path={`${match.path}/2`} render={() => <h2>two</h2>} />
    </Switch>
  </React.Fragment>
);

Тогда внутри инструкции маршрутизатора у меня есть:

const App = () => (

    <Router>
        <Navigation />
        <Switch>

            <Route path="/a" component={Admin} />
            <Route path="/u" component={Other} />
            <Route path="/p" component={Public} />

            <Route
                component={({ location }) => {
                  return (
                    <div
                      style={{
                        padding: "50px",
                        width: "100%",
                        textAlign: "center"
                      }}
                    >
                      <ErrorMessage />
                    </div>
                  );
                }}
              />
        </Switch>

    </Router>

);

export default App;

Это все работает, пока я не попытаюсь использовать константы маршрутов внутри части обратных тиков константа Admin.

Я не могу использовать этот подход.

Может ли кто-нибудь помочь с источником справочных материалов, чтобы найти способ через это?

1 Ответ

3 голосов
/ 18 апреля 2020

Есть несколько вещей, которые вам нужно знать

  1. Дочерние маршруты будут отображаться только при совпадении с родительским путем
  2. Для дочернего маршрута путь должен быть путем, который соответствует родительскому + дочернему пути маршрута
  3. Вы можете написать обертки по маршруту, которые отвечают за принятие решения, аутентифицирован ли пользователь или администратор
  4. Во всех таких сценариях ios необходимо хранить состояние аутентификации пользователя в хранилище состояний, контекста или избыточности.
  5. Когда вы визуализируете маршрут в Admin, как
<Route path={`${match.path}/${ROUTES.NEWBLOG}`} component={NewBlog} />

Путь к компоненту фактически становится /a/admin/newBlog, что на самом деле неверно

В целом вы можете изменить Ваш код к чему-то вроде этого

Приложение. js

const App = () => (
    <Router>
        <Navigation />
        <Switch>
            <Route path="/admin" component={Admin} />
            <Route path="/user" component={Other} />
            <Route path="/public" component={Public} />
        </Switch>
    </Router>
);

AuthRoute. js

const AuthRoute = (props) => {
   const {path, match, component: Component, render, ...rest} = props;
   const {user, isLoading} = useContext(AuthContext); // Assuming you use context to store route, you can actually get this values from redux store too.
   return (
      <Route
          {...rest}
          path={`${match.path}${path}`}
          render={(routerProps) => {
               if(isLoading) return <div>Loading...</div>
                if(!user) return <div>Not Authenticated</div>
               return Component? <Component {...rest} {...routerProps} /> : render(routerProps)
          }}
      />

}

Администратор должен проверить, является ли пользователь Администратор, а также проверить, если он аутентифицирован или нет, так что ваш компонент будет выглядеть как

AdminRoute. js

const AdminRoute = (props) => {
   const {path, match, ...rest} = props;
   const {user, isLoading} = useContext(AuthContext); // Assuming you use context to store route, you can actually get this values from redux store too.
   return (
      <Route
          {...rest}
          path={`${match.path}${path}`}
          render={(routerProps) => {
               if(isLoading) return <div>Loading...</div>
               if(!user) return <div>Not Authenticated</div>
               if(user.role !== "admin") return <div>Need to be an admin to access this route</div>
               return Component? <Component {...rest} {...routerProps} /> : render(routerProps)
          }}
      />

}

Теперь вы можете использовать два вышеупомянутых компоненты для разделения административных и аутентификационных маршрутов

Также следует учитывать, что пути маршрутов AuthRoutes и publi c не могут быть одинаковыми

Константы маршрутов

export const NEWBLOG = '/newblog';
export const VIEWBLOG = '/viewblog';

Маршруты

import * as ROUTES from '../../util/constants/Routes';
import NewBlog from '../../components/blog/admin/New';

// admin routes
const Admin = (props) => (
  <React.Fragment>
    <AdminRoute {...props} path={ROUTES.NEWBLOG} component={NewBlog} />
    <AdminRoute {...props} path='/2' render={() => <h2>test</h2>} />
  </React.Fragment>
);

// authenticated user routes
const Other = (props) => (
  <React.Fragment>
    <Switch>
      <AuthRoute {...props} path={'/3'} render={() => <h2>one</h2>} />
      <AuthRoute {...props} path={'/4'} render={() => <h2>two</h2>} />
    </Switch>
  </React.Fragment>
);

// public routes
const Public = ({ match }) => (
  <React.Fragment>
    <Switch>
      <Route path={`${match.path}/5`} render={() => <h2>one</h2>} />
      <Route path={`${match.path}/6`} render={() => <h2>two</h2>} />
    </Switch>
  </React.Fragment>
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...