Есть несколько вещей, которые вам нужно знать
- Дочерние маршруты будут отображаться только при совпадении с родительским путем
- Для дочернего маршрута путь должен быть путем, который соответствует родительскому + дочернему пути маршрута
- Вы можете написать обертки по маршруту, которые отвечают за принятие решения, аутентифицирован ли пользователь или администратор
- Во всех таких сценариях ios необходимо хранить состояние аутентификации пользователя в хранилище состояний, контекста или избыточности.
- Когда вы визуализируете маршрут в 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>
);