Маршрутизатор ReactJS иерархия компонентов при замене компонентов с изменением маршрута

#reactjs #react-router #react-router-dom

#reactjs #реагировать-маршрутизатор #react-router-dom

Вопрос:

TLDR: я пытаюсь выяснить, как упорядочить вложенные маршруты и мои компоненты, чтобы компонент можно было заменять на основе маршрута.

Проще говоря, я пытаюсь создать приложение, в котором учителя могут видеть классы, которые они преподают в колледжах.

Маршруты приложения являются:

  1. /dashboard : вызовите серверную часть, чтобы проверить, установлен ли колледж по умолчанию для преподавателя в их учетной записи, если нет, то отобразите диалоговое окно выбора колледжа, в котором преподаватель может выбрать колледж по умолчанию. Как только появится колледж по умолчанию (скажем COLLEGE1 ), перенаправьте на следующий маршрут (следующая маркерная точка)
  2. /dashboard/college/COLLEGE1 : извлекать метаданные классов, преподаваемых в колледже.
  3. /dashboard/college/COLLEGE1/class/CLASS1 : показывать метаданные одного класса внутри COLLEGE1 . Доступ к этому маршруту осуществляется щелчком по классу в маркере 2.

Вот грубые макеты того, как это взаимодействие будет выглядеть в статическом состоянии (я раскрасил каждый компонент, чтобы вам было легче ссылаться на них при ответе):

Грубые насмешки над взаимодействием

Однако я просто не могу определить структуру иерархии вложенных маршрутов компонентов, которая позволила бы мне это.

Иерархия, которую я имею до сих пор, является:

 <Home>
    <Header/>
        <!-- content in header -->
    </Header>
    <MainContent>
        <!-- Either loading, for e.g. to fetch permissions -->
        <Loading />

        <!-- OR display navigation   content -->
        <MainContentPage>
            <!-- show navigation pane on left, and then choose from report / T and Cs / Contact -->
            <Navigation>
                <CurrentCollegeInfo />
                <DashboardLink />
                <TermsAndConditionsLink />
                <ContactUsLink />
            </Navigation>

            <ReportPage>
                <!-- Either Loading -->
                <Loading />
                
                <!-- OR have user select default college -->
                <DefaultCollegePickerPopup />
            
                <!-- OR show college report or class details -->
                <CollegeReportPage />
                <ClassDetailsPage />    

                <!-- OR error pages: Not Found, 500, etc. -->
                <ErrorPage />
            </ReportPage>

            <TermsAndConditionsPage />
            <ContactUsPage />

        </MainContentPage>
    </MainContent>
</Home>
  

Как мне вставить здесь управление маршрутами (кстати, на данный момент я использую библиотеку react-router), чтобы в компоненте ReportPage:

  1. либо маршрут /dashboard (при загрузке колледжа по умолчанию из серверной части или при запросе пользователя выбрать один)
  2. или это /dashboard/college/COLLEGE1 и получение отчета колледжа
  3. или это /dashboard/college/COLLEGE1/class/CLASS1 и получение сведений о классе?

Или это невозможно, и я должен скорее определить другой поток?

Ответ №1:

Итак, если я правильно понимаю, вы хотите использовать react-router для загрузки различных компонентов в зависимости от того, на какой конечной точке находится пользователь? Это возможно на 100%. Вы просто передаете компонент, который хотите отобразить для определенного маршрута, в качестве свойства компонента.

Вы также можете использовать параметры в путях, поэтому в вашем примере у вас есть /dashboard/COLLEGE1 … Я предполагаю, что вам нужно, чтобы это было динамичным, чтобы разрешить любой колледж. Это делается с размещением параметров в path вот так … /dashboard/:somevariablename .

 <Route
    // exact

    path={"/dashboard"}
    // path={"/dashboard/:collegeId"}
    // path={"/dashboard/:collegeId/classes/:classId"}

    component={ComponentToPass}
/>
  

Если вы создадите Route для каждого возможного компонента / страницы, которую может посетить пользователь, и обернете его в <Switch> компонент, он будет отображать только один компонент. Однако вы можете пропустить <Switch> и добавить несколько маршрутов к конечной точке.

Я предполагаю, что вам нужно будет использовать collegeId и classId в соответствующих компонентах. Если вы используете функциональный react, используйте const { VARNAME } = useParams() для извлечения используемых вами параметров. Если вы используете react на основе классов, все, что вам нужно сделать, это вызвать this.props.match.VARNAME . — Оба, очевидно, используются внутри компонента, который вы хотите показать / использовать.

Итак, чтобы немного изменить ваш код (это можно сделать в выделенном компоненте routes), вот простой пример..

 import {HashRouter, Switch, Route} from "react-router-dom"
import DefaultCollegePickerPopup from './wherever'
import CollegeReportPage from './wherever'
import ClassDetailsPage from './wherever'

function RouterComponent(props) {

    return (
        <HashRouter>
            <Switch>

                <Route 
                    exact 
                    path={"/dashboard"}
                    component={DefaultCollegePickerPopup} 
                />
                <Route 
                    exact 
                    path={"/dashboard/:collegeId"} 
                    component={CollegeReportPage}
                />
                <Route 
                    exact 
                    path={"/dashboard/:collegeId/class/:classId"} 
                    component={ClassDetailsPage} 
                />
                
            </Switch>
        </HashRouter>
    )
}
  
 function CollegeReportPage(props) {
    const { collegeId } = useParams();

    return (
    <div>College report for {collegeId}</div>
    )
}

class CollegeReportPage extends React.Component {
    render() {
        const { collegeId } = this.props.match
        return (
            <div>College report for {collegeId}</div>
        )
    }
}
  

Если вы еще не посмотрели на это, я бы. Это дает много полезной информации.

https://reactrouter.com/web/guides/quick-start

Комментарии:

1. Большое спасибо за ответ. Я много изучал react router, но чего я не могу понять, так это как создать иерархию, чтобы заголовок и навигация всегда отображались во всех компонентах, без необходимости добавлять их в функцию визуализации 3 компонентов, указанных в маршрутах. Возможно ли это? Если да, то как?

2. Да, просто поместите навигацию и заголовок за пределы маршрутизатора. Все не обязательно должно быть внутри маршрутов. При этом теоретически у вас также может быть несколько маршрутизаторов, поэтому у вас может быть один коммутатор маршрутизатора, который контролирует половину вашего контента, а другой — вторую половину, если это то, что вам нужно будет сделать в будущем.

3. Я вижу, что понял. Я смог заставить его работать с вашим ответом, поэтому спасибо за помощь: D