Я новичок в реакции-маршрутизаторе (и маршрутизации на стороне клиента в целом), поэтому я могу думать об этом неправильно. Заранее извините, если это так ...
В основном просто хочу реализовать 3 простых правила:
Я отслеживаю пользователя в this.state.user. Мой текущий маршрутизатор, кажется, следует первым двум правилам, но только позволяет аутентифицированному пользователю видеть домашнюю страницу ('/ profile' перенаправляет на '/'), поэтому я знаю, что делаю что-то не так, но не могу понять, что именно.
<Router>
{this.state.user ? (
<Switch>
<Route path = "/" exact component = {Home}/>
<Route path = "/profile" exact component = {Profile}/>
<Route render = {() => (<Redirect to = "/" />)}/>
</Switch>
) : (
<Switch>
<Route path = "/login" exact component = {Login}/>
<Route render = {() => (<Redirect to = "/login" />)}/>
</Switch>
)}
</Router>
Любой совет приветствуется. Спасибо
Я попробовал тот же код в изолированной программной среде, и доступ к / profile осуществляется должным образом. Не могли бы вы проверить ссылку codeandbox.io/s/n422y545pl
Вам не нужно добавлять компонент Redirect в Switch. Вы должны установить условный рендеринг в каждом компоненте, в который вы хотите, чтобы пользователь входил в систему, т.е. Вы проверяете, вошел ли пользователь для просмотра маршрута, если нет. Затем вы визуализируете компонент Redirect, предоставляемый response-router-dom.
@RahilAhmad благодарит за пример. Я понял, что маршрутизация происходит до установки состояния пользователя.





Задумывались ли вы об использовании оболочки Route, которая проверяет пользователя, когда он необходим для Route?
const CanHasRouteAccess = ({ component: Component, iHasUser, ...rest }) => {
return iHasUser ? (
<Route {...rest} render = {props => <Component {...props} />} />
) : (
<Redirect to = "/" />
);
};
Вы можете передать реквизиты в Route или вызвать перенаправление на домашнюю страницу, когда пользователя нет.
<CanHasRouteAccess
path = "/personal-data"
exact
component = {Profile}
iHasUser = {Boolean(user)}
/>
Спасибо, Райан, это имеет смысл и работает. Есть идеи, как лучше всего справиться со случаем отсутствия согласованного маршрута с помощью перенаправления на '/'?
@Egor Если вы используете Route без пути в нижней части вашего Switch, он перехватит все несовпадающие маршруты. Например, <Route component = {NoMatch}/>. Источник
Для тех, кто приезжает сюда и ищет, как перенаправить, если ни один из маршрутов не совпадает:
<Switch>
// ... your routes
<Route render = {() => <Redirect to = "/" />} />
</Switch>
Обратите внимание, что маршруты должны быть прямыми потомками <Switch>, например. это не работает:
<Switch>
<Fragment>
// ... your routes
<Route render = {() => <Redirect to = "/" />} />
</Fragment>
</Switch>
(возможно, исправлено в более поздних версиях реактивного маршрутизатора)
у меня не работает. React router 4.3.1, Route вложен в Switch.
@VonAxt ставит его в последнюю очередь в переключателе.
Ответ прост
<Switch>
<Route path = "/login" exact component = {Login}/>
{!this.state.user && <Redirect to='/login' />}
<Route path = "/" exact component = {Home}/>
<Route path = "/profile" exact component = {Profile}/>
<Redirect to = "/" />
</Switch>
Основное различие между коммутатором и маршрутизатором заключается в том, что маршрутизатор будет пытаться выполнить все согласованные пути и добавить контент вместе, коммутатор остановится при первом совпадении.
В моем приложении используется аналогичный подход, но я обернул защищенную маршрутизацию в отдельный файл, а затем обернул профиль пользователя как HOC
export const App = () => (
<Switch>
<Route exact path='/login' component = {Login} />
{!hasToken() && <Redirect to='/login' />}
<Route path='/' component = {ProtectedRoute} />
</Switch>
)
protectedRoute.js
const ProtectedRoute = ({ userInfo }: Props) => (
<Layout userInfo = {userInfo}>
<Switch>
<Route exact path='/a' component = {A} />
<Route exact path='/b' component = {B} />
<Route path='/c' component = {C} />
<Redirect to='/a' />
</Switch>
</Layout>
)
export default withUserInfo(ProtectedRoute)
«Основное различие между коммутатором и маршрутизатором заключается в том, что маршрутизатор будет пытаться выполнить все согласованные пути и добавить контент вместе, коммутатор остановится при первом совпадении». Это заявление помогло мне предотвратить бесчисленное количество часов выдергивания волос.
Можете ли вы просто попробовать <Route component = {Home} /> перенаправить на корневой (домашний) компонент, если маршрут не найден?