Lazy loading routes in react router v6

7k Views Asked by At

I'm trying to lazy load route elements with the createBrowserRouter function in React Router v6 but I keep getting this error: `Matched leaf route at location "/admin/reports/enrollees" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page. This is my routes file:

export default createBrowserRouter([
    {
        path: '/admin/reports',
        children: [
            {
                path: '',
                element: <Index />,
            },
            {
                path: 'enrollees',
                lazy: () => import('../../components/Reports/Enrollees'),
            },
            {
                path: 'facilities',
                lazy: () => import('../../components/Reports/Facilities'),
            }
        ],
    }
])

I tried doing this at first:

export default createBrowserRouter([
    {
        path: '/admin/reports',
        children: [
            {
                path: '',
                element: <Index />,
            },
            {
                path: 'enrollees',
                element: lazy(() => import('../../components/Reports/Enrollees')),
            },
            {
                path: 'facilities',
                element: lazy(() => import('../../components/Reports/Facilities')),
            }
        ],
    }
])

But I got the error: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.

2

There are 2 best solutions below

0
On BEST ANSWER

I was facing the same issue, i resolved it this way

{
  path: "dashboard",
  lazy: async () => {let { Dashboard } = await import("./pages/Dashboard")
    return { Component: Dashboard }},  
}
1
On

This strange problem had been bothering me for a few hours, but I finally figured out the problem

First make sure your component's name is Component, then use named export instead of default export

eg. YourComponent.jsx

export function Component(){
  return <div>something</div>
}

the route object

{
  path: 'your-component',
  lazy: () => import('./YourComponent'),
}

If you want to keep your component name and also use default export, you can do

eg. YourComponent.jsx

export default function YourComponent(){
  return <div>something</div>
}

the route object

{
  path: 'your-component',
  async lazy() {
    let YourComponent = await import("./YourComponent");
    return { Component: YourComponent.default };
  },
}