React Router DOM 6.22: Индексная страница не отображается для многослойных вложенных маршрутов

Вопрос или проблема

У меня есть несколько вложенных маршрутов, однако компонент маршрута индекса, который находится на глубине 2 уровня, не отображается и просто показывает пустую страницу.

// Я не могу добавить свойство `index`, потому что не может быть дочерних маршрутов, если это маршрут индекса.

export const routes= [
  { 
    // Добавьте элемент навигации, поскольку маршруты индекса не могут иметь детей. 
    // Если этот навигатор будет удален, он не сможет перенаправить с использованием индекса.
    element: () => <Navigate to={`one`} />,
    path: "https://stackoverflow.com/",
    name: 'default',
    children: [
      {
        // Как только осуществляется переход на этот маршрут из маршрута по умолчанию `/`, он просто отображает пустую страницу, а не компонент `NestedComponentOne`
        element: NestedComponentOne,
        path: 'one',
        name: 'Одно',
        children: [
          {
            element: DeeplyNestedComponentOne,
            name: 'Глубокое Один',
            path: 'deep-one',
          },
          {
            element: DeeplyNestedComponentTwo,
            name: 'Глубокое Два',
            path: 'deep-two',
          },
        ]
      },
    ]
  }
]

const MyComponent= () => {
  return (
    <>
      <div style={{ margin: "0px 0px" }}>
        <Routes>
          {routes.map((route, idx) => {
            if (route.children && route.children.length > 0) {
              return (
                <Route
                  key={`child-routes-auth-${idx}`}
                  element={route?.element && <route.element />}
                  errorElement={route?.errorElement}
                  name={route.name}
                  path={route.path}
                >
                  {route.children.map((childRoute, childIdx) => {
                    if (childRoute.children && childRoute.children.length > 0) {
                      return (
                        <Route
                          key={`inner-child-auth-routes-${childIdx}`}
                          element={childRoute?.element && <childRoute.element />}
                          errorElement={childRoute?.errorElement}
                          name={childRoute.name}
                          path={childRoute.path}
                        >
                          {childRoute.children.map((innerRoutes, innerIndex) => {
                            return (
                              innerRoutes.element && (
                                <Route
                                  key={`nested-inner-auth-${innerIndex}`}
                                  element={innerRoutes?.element && <innerRoutes.element />}
                                  errorElement={innerRoutes?.errorElement}
                                  index={innerRoutes?.index}
                                  name={innerRoutes.name}
                                  path={innerRoutes.path}
                                />
                              )
                            )
                          })}
                        </Route>
                      )
                    }
                    return (
                      childRoute.element && (
                        <Route
                          key={`childIdx-auth-${childIdx}`}
                          element={childRoute?.element && <childRoute.element />}
                          errorElement={childRoute?.errorElement}
                          index={childRoute?.index}
                          name={childRoute.name}
                          path={childRoute.path}
                        />
                      )
                    )
                  })}
                </Route>
              )
            }
            return (
              route.element && (
                <Route
                  key={`top-routes-${idx}`}
                  element={<route.element />}
                  errorElement={route?.errorElement}
                  index={route?.index}
                  path={route.path}
                  name={route.name}
                />
              )
            )
          })}
        </Routes>
      </div>
    </>
  );
}

Ответ или решение

Для решения проблемы с неотображением компонента индексного маршрута на втором уровне вложенных маршрутов в React Router v6.22, давайте проанализируем ваш код и внесем некоторые изменения. Ваша основная проблема заключается в том, что индексные маршруты не могут иметь дочерние маршруты, поэтому необходимо правильно настроить вашу маршрутизацию. Я предложу вам пример, который будет корректно обрабатывать ваши маршруты и обеспечивать рендеринг необходимых компонентов.

Шаги для устранения проблемы:

  1. Структура маршрутов: Убедитесь, что индексный маршрут на втором уровне правильно определен. Мы добавим дополнительный уровень для управления вложенными маршрутами и убедимся, что компонент, который вы хотите отобразить (например, NestedComponentOne), действительно рендерится по соответствующему пути.

  2. Маршрутизация: Вы можете воспользоваться index маршрутом для рендеринга по умолчанию, когда путь соответствует родительскому маршруту.

Обновленный код

Вот пример вашей маршрутизации с корректной настройкой вложенных маршрутов и индексного маршрута:

import { Routes, Route, Navigate } from 'react-router-dom';

const NestedComponentOne = () => <div>Nested Component One</div>;
const DeeplyNestedComponentOne = () => <div>Deeply Nested Component One</div>;
const DeeplyNestedComponentTwo = () => <div>Deeply Nested Component Two</div>;

export const routes = [
  {
    path: "/", // базовый путь
    element: <Navigate to="one" />, // перемещаемся к индексу
    name: 'default',
    children: [
      {
        path: "one", // значение для первого уровня
        element: <NestedComponentOne />, // Компонент по умолчанию
        name: 'One',
        children: [
          {
            path: "deep-one",
            element: <DeeplyNestedComponentOne />, // Глубокий компонент один
            name: 'Deep One',
          },
          {
            path: "deep-two",
            element: <DeeplyNestedComponentTwo />, // Глубокий компонент два
            name: 'Deep Two',
          },
          // индексный маршрут для рендеринга по умолчанию
          {
            index: true,
            element: <Navigate to="deep-one" /> // или любой другой компонент по умолчанию
          }
        ],
      },
    ],
  },
];

const MyComponent = () => {
  return (
    <div style={{ margin: "0px 0px" }}>
      <Routes>
        {routes.map((route, idx) => (
          <Route
            key={`route-${idx}`}
            path={route.path}
            element={route.element}
          >
            {route.children && route.children.map((childRoute, childIdx) => (
              <Route
                key={`childRoute-${childIdx}`}
                path={childRoute.path}
                index={childRoute.index}
                element={childRoute.element}
              />
            ))}
          </Route>
        ))}
      </Routes>
    </div>
  );
}

export default MyComponent;

Объяснение изменений:

  1. Индексный маршрут: Мы добавили индексный маршрут в массив children для маршрута one, который будет перенаправлять на deep-one или любой другой компонент по умолчанию, если на данный путь нет других специфических компонентов.

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

  3. Упрощение кода: Мы упростили код, убрав лишние проверки, сводя к минимуму условия в map вызовах.

Заключение

С этими изменениями ваш индексный маршрут должен корректно рендериться, и вы должны видеть NestedComponentOne по пути /one, а также компоненты DeeplyNestedComponentOne и DeeplyNestedComponentTwo по соответствующим путям. Если у вас возникнут дополнительные вопросы или потребуется дальнейшая помощь, пожалуйста, дайте знать!

Оцените материал
Добавить комментарий

Капча загружается...