Search code examples
reactjsreact-router-dom

route param comparison is undefined (react-router-dom v6)


I running circles with this one. Thanks in advance for all the help you could provide.

The issue is whith the way of accessing a view for a single item in an array. The id param is passed in the address and accessed with useMatch() from react-router-dom. (Edit: example bellow also shows code with the use of useParams as I tried to follow other user's use cases)

The id from the match.params seems the same as one of the items' array (as it should be) Unfortunately, running array.find() doesn't end with a positive result, rather an undefined value.

I searched the web for details on this and maybe this is to do with v6 of the React Router ?

Doing the final exercice of the full-stack-open part 7: https://fullstackopen.com/en/part7/exercises_extending_the_bloglist#exercises-7-9-7-21

I finally ended up asking AI for debbugging but it made me check for everything I already did.

Here is the code from the Component :

                {[...users].map(u =>
                    <tr key={u.id}>
                        <td><Link to={`/users/${u.id}`}>{u.id}</Link></td>
                        <td>{u.blogs.length}</td>
                    </tr>
                )}

Here is the App.jsx (wrapped in main.jsx by BrowserRouter) :

import { Routes, Route, Link, useParams } from 'react-router-dom'

const App = () => {
    useEffect(() => {
        userService.getAll()
          .then(users => {
            setUserList(users)
            console.log('UserList:', users) // Verify the structure and content of userList
          })
          .catch(error => console.error('Error fetching users:', error))
      }, [])
    // With useMatch() //////
const userMatch = useMatch('/users/:id')
  console.log('userMatch id: ', String(userMatch.params.id))
  console.log('userList id: ', String(userList[0].id))


  const u = userMatch && userList > 0
    ? userList.find(u => String(u.id) === String(userMatch.params.id))
    : null
  console.log('User found:', u) // Log the found user


// With useParams() ////////////
    let { id } = useParams() // Get the id parameter directly
      console.log('Params ID:', id) // Log the id parameter
      console.log('UserList:', userList) // Log the userList contents
    
      const u = userList.length > 0
        ? userList.find((u) => {
          console.log('Checking user:', u.id, 'with ID:', id) // Log the comparison
          return Number(u.id) === Number(id)
        })
        : null
    
      console.log('User found:', u) // Log the found user

return (
<div>
  <div>
    <Link to='/'>Home</Link>
    <Link to='/users'>Users</Link>
  </div>

  <div>
    <h2>blogs</h2>
    <Notification notification={notification} />
    <div>
      {users.name} logged in
      <button onClick={handleLogout}>
        logout
      </button>
    </div>
    <Routes>
      <Route path='/users/:id' element={<User user={u} />} />
      <Route path='/users' element={<Users users={userList} />} />
      <Route path='/' element={<Home />} />
    </Routes>

  </div>
</div>

)

console view

Those tests were done and ok-ed :

  1. Verify Router Setup:
    Ensure that BrowserRouter (or HashRouter) is correctly wrapping your App component in the root file (index.js or equivalent):

  2. Check URL and Routing Configuration:
    Ensure the URL matches the route pattern defined in your Routes. For example, if the route is "/users/:id", the URL should be something like http://localhost:3000/users/1.

  3. Test useParams in Isolation:
    Simplify the component to directly test useParams and see if it correctly extracts the id:

  4. Simplify App for Debugging:
    Create a minimal version of App just to test routing:

  5. Check userList Contents:
    If useParams correctly extracts the id, then the issue might lie in how userList is being populated or accessed.

  6. Cross-Verify user.id Type:
    Ensure that user.id in userList matches the type of id extracted from useParams.


Solution

  • So... TLDR: redid the project from the working logic

    I started again from the sandbox code made by Drew Reese from my project: https://codesandbox.io/p/sandbox/busy-water-2rpdcz

    After moving components to their own files and adding the backend import for the userList, it still worked and I am now able to complete the exercice.

    I am still puzzled to this day at what was the issue with my previous code.