Как работает <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>

Это также будет полностью допустимо, но единственное, что когда-либо будет отображено, это "Привет!!" потому что это первый соответствующий компонент.

Другие вопросы по тегам