Как работает <Switch>, когда он встречает в себе компоненты React?
В основном я понимаю чей-то код и модифицирую. В App.js проверяется, вошел ли пользователь в систему, он должен рендерить панель инструментов
App.js
<Switch>
<Redirect exact path="/" to="/dashboard"/>
<Route path="/login" component={GuestBoard} />
<EnsureSignedIn>
<Switch>
<Route path="/dashboard/" component={Dashboard}/>
<Route path="/welcome/" component={Welcome}/>
</Switch>
</EnsureSignedIn>
</Switch>
В принципе <EnsureSignedIn>
проверяет, вошел ли пользователь в систему, он отображает все дочерние элементы.
Мой вопрос: как <Switch>
оказывает <EnsureSignedIn>
который не имеет пути. А также, что именно происходит (как выглядит процесс рендеринга компонентов), если я продолжаю писать React Components внутри <Switch>
?
Скажи что-то вроде этого
<Switch>
<Redirect exact path="/" to="/dashboard"/>
<Route path="/login" component={GuestBoard} />
<Component1 />
<Component2 />
<Component3 />
</Switch>
EnsureSignedIn:
componentDidMount() {
if (!this.props.user) {
this.props.history.push('/login?next=' + this.props.currentURL);
}
render() {
return (this.props.user ? this.props.children : null);
}
Мы использовали редукс, так что пользователь реквизит от редуктора.
1 ответ
Коммутатор работает, как задумано, хотя в документации рекомендуется только Route
или же Redirect
Компонент как прямой ребенок. Однако задокументировано, что Switch будет отображать одного дочернего элемента - первого дочернего элемента, который соответствует текущему маршруту. Он также указывает, что <Route
Компонент без пути разрешен как универсальное средство, именно это и происходит здесь.
Чтобы упростить, Switch будет перебирать все свои дочерние элементы, один за другим, сверху вниз и выбирать первый компонент, где путь соответствует текущему маршруту, или у компонента не указан путь (компонент catch-all). Вы можете увидеть это здесь: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Switch.js#L47 обратите внимание, что он ищет реквизиты Route
компонент, но нет кода, специально требующего, чтобы компонент был Route
,
В вашем случае неаутентифицированные страницы будут отображаться очень хорошо, потому что они появляются до EnsureSignIn
дочерний компонент. Однако, если другие маршруты не совпадают, EnsureSignIn
будет отображаться, и, по-видимому, этот компонент будет перенаправлен обратно на страницу входа в систему, если пользователь не вошел в систему, что не позволит им получить доступ к защищенным страницам ниже.
Если бы вы реструктурировали свой код следующим образом:
<Switch>
<span>Hello!!</span>
<Redirect exact path="/" to="/dashboard"/>
<Route path="/login" component={GuestBoard} />
<EnsureSignedIn>
<Switch>
<Route path="/dashboard/" component={Dashboard}/>
<Route path="/welcome/" component={Welcome}/>
</Switch>
</EnsureSignedIn>
</Switch>
Это также будет полностью допустимо, но единственное, что когда-либо будет отображено, это "Привет!!" потому что это первый соответствующий компонент.