Company logo
  • Empleos
  • Bootcamp
  • Acerca de nosotros
  • Para profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
    • Bootcamp
  • Para empresas
    • Inicio
    • Nuestro proceso
    • Planes
    • Pruebas
    • Nómina
    • Blog
    • Calculadora

0

70
Vistas
How to make a Not Found page with complex dymanic nested routes in React Router 6?

How to make a Not Found page with complex dynamic nested routes in React Router 6?

For example I have dynamic routes for categories and product pages. It looks like this:

site.com/jeans
site.com/jeans/qazXzx123122

To render the data on category and product pages I use the same approach:

  • Get URL from useParams
  • Find category and products with the same URL in Redux-state
  • Render data on a page

CategoryPage

const { products } = useSelector((state: RootState) => state.product);
const { categories } = useSelector((state: RootState) => state.category);
const { url } = useParams();
const categoryProducts = products.filter((product) => product.category.url === url);
const category = categories.find((category) => category.url === url) as Category;

If I go to wrong URL e.g. to site.com/jeans111 then app crashes because there's no category with that URL and category === undefined. I tried to solved the problem with useEffect hook and redirect but no success.

Not working approach

useEffect(() => {
  if (!category.name) {
    return navigate('/', {
      replace: true,
    });
  }
}, [category, navigate]);

Routes

const routes = useRoutes([
  {
    path: PATHS.showcase,
    element: <ShowcasePage />,
    children: [
      {
        path: '/',
        element: isDataLoaded ? <DiscountProductsPage /> : <Loader />,
      },
      {
        path: ':url',
        children: [
          {
            index: true,
            element: isDataLoaded ? <CategoryPage /> : <Loader />,
          },
          {
            path: ':id',
            element: isDataLoaded ? <ProductPage /> : <Loader />,
          },
          {
            path: '*',
            element: <NotFound />
          }
        ],
      },
      { path: PATHS.wishlist, element: isDataLoaded ? <WishlistPage /> : <Loader /> },
      {
        path: PATHS.cart,
        element: isDataLoaded ? <CartPage /> : <Loader />,
      },
      {
        path: `${PATHS.cart}/${PATHS.success}`,
        element: <CheckoutSuccessPage />,
      },
    ],
  },
  {
    path: PATHS.admin,
    element: <AdminPage />,
    children: [
      {
        path: PATHS.orders,
        element: <OrdersPage />,
      },
      {
        path: PATHS.products,
        element: <ProductsPage />,
      },
      {
        path: PATHS.settings,
        element: <SettingsPage />,
      },
    ],
  },
]);
5 months ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

I think your approach is correct, but you want to redirect off the route when there is no category to render content for.

Example:

const navigate = useNavigate();
const { url } = useParams();
...
const category = categories.find((category) => category.url === url) as Category;

useEffect(() => {
  if (!category) {
    navigate('/', { replace: true });
  }
}, [category, navigate]);

Though it may be better to display a fallback screen instead of just bouncing the user off the route.

const navigate = useNavigate();
const { url } = useParams();
...
const category = categories.find((category) => category.url === url) as Category;

...

return category
  ? (
    ...JSX...
  )
  : (
    <div>No match found.</div>
  );
5 months ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar empleo Planes Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2023 PeakU Inc. All Rights Reserved.