skip to Main Content
import { RouterProvider, createBrowserRouter } from "react-router-dom"
import AppLayout from "./ui/AppLayout"
import Questions, {loader as questionsLoader} from './features/questions/Questions'
import Companies from './features/companies/Companies'
import Users, {loader as usersLoader} from './features/users/Users'
import Tags from './features/tags/Tags'
import Error from './ui/Error'
import User, {loader as userLoaderById} from "./features/users/User"

const router = createBrowserRouter([
  {
    path: '/',
    element: <AppLayout />,
    errorElement: <Error />,
    children: [
      {
        path: '/questions',
        element: <Questions />,
        loader: questionsLoader,
        errorElement: <Error />
      },
      {
        path: '/companies',
        element: <Companies />
      },
      {
        path: '/users',
        element: <Users />,
        loader: usersLoader,
        errorElement: <Error />
      },
      {
        path: '/users/:userId',
        element: <User />,
        loader: userLoaderById,
        errorElement: <Error />
      },
      {
        path: '/tags',
        element: <Tags />,
        // loader: tagsLoader,
        // errorElement: <Error/>
      }
    ]
  }
])

function App() {
  return (
    <RouterProvider router={router} />
  )
}

export default App

Helper function for async task

export async function getDataById (id) {   
   let res = await fetch(`${BASE_URL}/users/${id}?pagesize=50&site=stackoverflow&key=${API_KEY}`);      
   if(!res.ok) throw new Error(" Oops! Targer user's record not found 😔")
   let { items } = await res.json();
   return items;
}
import { useLoaderData } from "react-router-dom"
import { getDataById } from "../../utils/helpers";

const User = () => {
  const data = useLoaderData()
    
  return (
    <div>User</div>
  )
}

export async function loader(params) {
  console.log(params.userId);
    
  let userData = await getDataById(params.userId);    
  return userData
}

export default User

I’m trying to get specific user by id. Inside my loader, params have userId along with other data, but as I tried to pass it to helper function, which is responsible for data fetching, I found it undefined and it gives me error like

helpers.js?t=1694052786647:37 GET
https://api.stackexchange.com/2.3/users/undefined?pagesize=50&site=stackoverflow&key=Yop5T7opvZcqG255X2YmsQ((
400 (Bad Request).

2

Answers


  1. Route loader functions take a single argument object that has params and request properties. You should destructure params from this argument.

    export async function loader({ params }) {
      console.log(params.userId);
        
      const userData = await getDataById(params.userId);    
      return userData;
    }
    
    Login or Signup to reply.
  2. The issue seems to be in createBrowserRouter. In React Router, routes are evaluated from top to bottom, and the first route that matches the URL will be used. If you have a route like /users before /users/:userId, it will match the /users route for URLs like /users/123 because /users is also a prefix of /users/123.

    So to resolve this issue you should have something like this:

    const router = createBrowserRouter([
      {
        path: '/',
        element: <AppLayout />,
        errorElement: <Error />,
        children: [
          {
            path: '/questions',
            element: <Questions />,
            loader: questionsLoader,
            errorElement: <Error />
          },
          {
            path: '/companies',
            element: <Companies />
          },
          {
            path: '/users/:userId',
            element: <User />,
            loader: userLoaderById,
            errorElement: <Error />
          },
          {
            path: '/users',
            element: <Users />,
            loader: usersLoader,
            errorElement: <Error />
          },
          {
            path: '/tags',
            element: <Tags />,
            // loader: tagsLoader,
            // errorElement: <Error/>
          }
        ]
      }
    ])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search