Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
menu
  1. Home
  2. /Web Development
  3. /React
  4. /Dynamic Routes
Your Progress0%
0 of 42 completed

React Topics

Getting Started

  • What is React?
  • React vs Vanilla JavaScript
  • Setting Up Your Environment
  • Your First React App

JSX Fundamentals

  • Introduction to JSX
  • JSX Expressions and Variables
  • Conditional Rendering
  • Lists and Keys
  • Styling in JSX

Components Basics

  • Function Components
  • Props
  • Children Prop
  • Props Destructuring
  • Component Composition

State Management

  • Introduction to State
  • useState Hook
  • State Updates and Re-renders
  • Multiple State Variables
  • State Best Practices

Events and Interactivity

  • Handling Events
  • Event Objects
  • Forms in React
  • Form Validation

Side Effects and Data

  • Introduction to useEffect
  • Data Fetching
  • Cleanup Functions
  • Dependency Arrays

Advanced Hooks

  • useRef Hook
  • useContext Hook
  • useMemo Hook
  • useCallback Hook

React Patterns

  • Custom Hooks
  • Higher-Order Components
  • Render Props Pattern

React Router

  • Introduction to React Router
  • Routes and Navigation
  • Dynamic Routes and Parameters

Best Practices

  • Component Organization
  • Performance Optimization
  • Error Handling
  • Testing React Components

Real World Project

  • Building a Complete App

Dynamic Routes and Parameters

Working with URL parameters and flexible routes

Real applications need routes that can handle dynamic data. Instead of creating separate routes for every user, product, or post, you can use dynamic routes with URL parameters. A single route like /users/:id can handle /users/1, /users/2, and any other user ID. You'll also learn about query strings for filtering and search. Let's build flexible, data-driven routes! šŸŽÆ

URL Parameters (Route Parameters)

URL parameters let you capture values from the URL:

Defining Dynamic Routes

dynamic-route-definition.jsx
import { Routes, Route } from 'react-router-dom'

function App() {
  return (
    <Routes>
      {/* Static routes */}
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      
      {/* Dynamic route with parameter */}
      <Route path="/users/:id" element={<UserDetail />} />
      {/* :id is a parameter - can be any value */}
      
      {/* Multiple parameters */}
      <Route path="/posts/:year/:month/:slug" element={<BlogPost />} />
      
      {/* Nested dynamic routes */}
      <Route path="/users/:userId/posts/:postId" element={<UserPost />} />
    </Routes>
  )
}

// URL matching:
// /users/123        → UserDetail with id=123
// /users/456        → UserDetail with id=456
// /users/alice      → UserDetail with id=alice
// /posts/2024/12/hello → BlogPost with year=2024, month=12, slug=hello

// Parameters start with : in the route path

Accessing Parameters with useParams

use-params.jsx
import { useParams } from 'react-router-dom'

function UserDetail() {
  // Get parameters from URL
  const { id } = useParams()
  
  const [user, setUser] = React.useState(null)
  const [loading, setLoading] = React.useState(true)
  
  React.useEffect(() => {
    // Fetch user data using the ID from URL
    fetch(`/api/users/${id}`)
      .then(res => res.json())
      .then(data => {
        setUser(data)
        setLoading(false)
      })
  }, [id])  // Re-fetch when ID changes
  
  if (loading) return <div>Loading...</div>
  if (!user) return <div>User not found</div>
  
  return (
    <div>
      <h1>{user.name}</h1>
      <p>Email: {user.email}</p>
      <p>User ID: {id}</p>
    </div>
  )
}

// Usage:
// URL: /users/123  → id = "123"
// URL: /users/456  → id = "456"

// useParams returns an object with all parameters as strings!

Multiple Parameters

multiple-params.jsx
import { useParams } from 'react-router-dom'

// Route: /posts/:year/:month/:slug
function BlogPost() {
  const { year, month, slug } = useParams()
  
  React.useEffect(() => {
    // Fetch post using all parameters
    fetch(`/api/posts/${year}/${month}/${slug}`)
      .then(res => res.json())
      .then(data => setPost(data))
  }, [year, month, slug])
  
  return (
    <div>
      <h1>Blog Post</h1>
      <p>Year: {year}</p>
      <p>Month: {month}</p>
      <p>Slug: {slug}</p>
    </div>
  )
}

// URL: /posts/2024/12/react-tutorial
// year = "2024"
// month = "12"
// slug = "react-tutorial"

// All parameters are strings - convert if needed:
const yearNum = parseInt(year, 10)
const monthNum = parseInt(month, 10)

Important: Parameters Are Strings!

useParams always returns strings, even if the URL contains numbers.

URL: /users/123
Result: id = "123" (string, not number)

Convert to number when needed:
const userId = parseInt(id, 10)
const userId = Number(id)

Query Strings (Search Parameters)

Query strings add extra data to URLs after the ?:

Using useSearchParams

use-search-params.jsx
import { useSearchParams } from 'react-router-dom'

function ProductList() {
  const [searchParams, setSearchParams] = useSearchParams()
  
  // Read query parameters
  const category = searchParams.get('category') || 'all'
  const sort = searchParams.get('sort') || 'name'
  const page = searchParams.get('page') || '1'
  
  const [products, setProducts] = React.useState([])
  
  React.useEffect(() => {
    // Fetch filtered products
    fetch(`/api/products?category=${category}&sort=${sort}&page=${page}`)
      .then(res => res.json())
      .then(data => setProducts(data))
  }, [category, sort, page])
  
  // Update query parameters
  const handleCategoryChange = (newCategory) => {
    setSearchParams({ category: newCategory, sort, page })
  }
  
  const handleSortChange = (newSort) => {
    setSearchParams({ category, sort: newSort, page })
  }
  
  return (
    <div>
      <h1>Products</h1>
      
      {/* Filters */}
      <select value={category} onChange={e => handleCategoryChange(e.target.value)}>
        <option value="all">All</option>
        <option value="electronics">Electronics</option>
        <option value="clothing">Clothing</option>
      </select>
      
      <select value={sort} onChange={e => handleSortChange(e.target.value)}>
        <option value="name">Name</option>
        <option value="price">Price</option>
        <option value="date">Date</option>
      </select>
      
      {/* Product list */}
      {products.map(product => (
        <div key={product.id}>{product.name}</div>
      ))}
    </div>
  )
}

// URL examples:
// /products?category=electronics&sort=price&page=2
// category = "electronics"
// sort = "price"
// page = "2"

// Benefits:
// - Shareable URLs with filters
// - Browser back/forward works with filters
// - Bookmarkable search results

Query String Patterns

query-patterns.jsx
import { useSearchParams, useNavigate } from 'react-router-dom'

function SearchPage() {
  const [searchParams, setSearchParams] = useSearchParams()
  const navigate = useNavigate()
  
  // Reading parameters
  const query = searchParams.get('q')           // /search?q=react
  const page = searchParams.get('page')         // /search?page=2
  const filter = searchParams.get('filter')     // /search?filter=recent
  
  // Check if parameter exists
  const hasQuery = searchParams.has('q')
  
  // Get all values (if multiple values for same key)
  const tags = searchParams.getAll('tag')       // /search?tag=react&tag=hooks
  
  // Setting parameters (replaces all)
  setSearchParams({ q: 'react', page: '1' })
  // URL becomes: /search?q=react&page=1
  
  // Updating parameters (preserves others)
  setSearchParams(prev => {
    prev.set('page', '2')  // Update page
    return prev
  })
  
  // Deleting parameters
  setSearchParams(prev => {
    prev.delete('filter')  // Remove filter
    return prev
  })
  
  // Multiple updates at once
  const updateFilters = (newFilters) => {
    setSearchParams(prev => {
      Object.entries(newFilters).forEach(([key, value]) => {
        if (value) {
          prev.set(key, value)
        } else {
          prev.delete(key)
        }
      })
      return prev
    })
  }
  
  return <div>Search Page</div>
}

// Common patterns:
// - Pagination: ?page=2
// - Sorting: ?sort=name&order=asc
// - Filtering: ?category=electronics&price_min=100
// - Search: ?q=react+hooks
// - Multiple filters: ?tag=react&tag=hooks&tag=tutorial

Interactive Demo

ReactPlayground.jsx
Code Editor
Preview

šŸ’” Tip: Edit the code above and click "Run" to see your changes

Optional Parameters

Create routes where parameters are optional:

optional-params.jsx
import { Routes, Route, useParams } from 'react-router-dom'

function App() {
  return (
    <Routes>
      {/* Both with and without parameter */}
      <Route path="/blog" element={<BlogList />} />
      <Route path="/blog/:slug" element={<BlogPost />} />
    </Routes>
  )
}

function BlogPost() {
  const { slug } = useParams()
  
  if (!slug) {
    // This won't happen with this route structure,
    // but useful for other patterns
    return <div>No post selected</div>
  }
  
  return <div>Post: {slug}</div>
}

// Alternative: Use query string for optional data
function App() {
  return (
    <Routes>
      <Route path="/blog" element={<Blog />} />
    </Routes>
  )
}

function Blog() {
  const [searchParams] = useSearchParams()
  const slug = searchParams.get('post')  // /blog?post=my-post
  
  if (slug) {
    return <BlogPost slug={slug} />
  }
  
  return <BlogList />
}

// URL parameters vs Query strings:
// Required data → URL parameter (/users/:id)
// Optional data → Query string (/search?q=react)

Catch-All Segments

Match multiple path segments with the * wildcard:

catch-all.jsx
import { Routes, Route, useParams } from 'react-router-dom'

function App() {
  return (
    <Routes>
      {/* Catch-all route for docs */}
      <Route path="/docs/*" element={<Documentation />} />
      
      {/* 404 catch-all */}
      <Route path="*" element={<NotFound />} />
    </Routes>
  )
}

function Documentation() {
  const { '*': splat } = useParams()
  // splat contains everything after /docs/
  
  // /docs/getting-started/installation
  // splat = "getting-started/installation"
  
  return (
    <div>
      <h1>Documentation</h1>
      <p>Section: {splat}</p>
    </div>
  )
}

// Use cases:
// - File browsers (/files/documents/2024/report.pdf)
// - Documentation (/docs/react/hooks/useState)
// - Deep linking (/app/workspace/project/task/subtask)

Combining URL Patterns

Real apps often combine parameters and query strings:

combined-patterns.jsx
import { useParams, useSearchParams } from 'react-router-dom'

// Route: /users/:userId/posts
function UserPosts() {
  // Get route parameter
  const { userId } = useParams()
  
  // Get query parameters
  const [searchParams] = useSearchParams()
  const page = searchParams.get('page') || '1'
  const sort = searchParams.get('sort') || 'date'
  const filter = searchParams.get('filter') || 'all'
  
  React.useEffect(() => {
    // Fetch user's posts with filters
    fetch(`/api/users/${userId}/posts?` + new URLSearchParams({
      page,
      sort,
      filter
    }))
      .then(res => res.json())
      .then(data => setPosts(data))
  }, [userId, page, sort, filter])
  
  return (
    <div>
      <h1>Posts by User {userId}</h1>
      <p>Page {page} | Sort: {sort} | Filter: {filter}</p>
    </div>
  )
}

// Example URLs:
// /users/123/posts
// /users/123/posts?page=2
// /users/123/posts?page=2&sort=likes&filter=published

// Pattern:
// - Use route params for required resource IDs
// - Use query params for optional filtering/pagination

Navigating with Parameters

navigate-params.jsx
import { useNavigate, Link } from 'react-router-dom'

function UserList({ users }) {
  const navigate = useNavigate()
  
  const handleUserClick = (userId) => {
    // Navigate with URL parameter
    navigate(`/users/${userId}`)
  }
  
  const handleSearch = (query) => {
    // Navigate with query string
    navigate(`/search?q=${encodeURIComponent(query)}`)
  }
  
  const handleFilteredView = (category, sort) => {
    // Navigate with multiple query params
    navigate(`/products?` + new URLSearchParams({
      category,
      sort,
      page: '1'
    }))
  }
  
  return (
    <div>
      {users.map(user => (
        <div key={user.id}>
          {/* Link with parameter */}
          <Link to={`/users/${user.id}`}>
            {user.name}
          </Link>
          
          {/* Button navigation */}
          <button onClick={() => handleUserClick(user.id)}>
            View Profile
          </button>
        </div>
      ))}
    </div>
  )
}

// Tips:
// - Use template literals for params
// - Use URLSearchParams for query strings
// - Use encodeURIComponent for special characters

Dynamic Routes Best Practices

  • Use URL params for required IDs - /users/:id
  • Use query strings for optional filters - ?sort=name
  • Always validate parameter types - Convert strings to numbers
  • Handle missing/invalid params gracefully - Show 404 or redirect
  • Keep URLs readable and SEO-friendly - Use slugs, not just IDs
  • Encode special characters - Use encodeURIComponent
  • Make URLs shareable - Include all necessary data
  • Use consistent naming - /users/:userId not /users/:id
  • Document your URL structure - For team reference
  • Consider nested resources - /users/:userId/posts/:postId
  • Avoid too many parameters - Maximum 3-4 per route

Common Pitfalls:

  • Type errors: Remember params are strings!
  • Not handling null: Check if param exists
  • Special characters: Always encode/decode
  • Route conflicts: /users/new vs /users/:id (put specific routes first)
  • Missing validation: Check param format before use

Key Takeaways

  • Dynamic routes use :paramName syntax
  • useParams accesses URL parameters
  • All parameters are strings - convert when needed
  • useSearchParams handles query strings
  • URL params for required data (IDs, slugs)
  • Query strings for optional data (filters, pagination)
  • Multiple parameters supported: /:year/:month/:slug
  • Catch-all routes with * wildcard
  • Combine params and query strings for complex routes
  • Always validate and handle invalid parameters
  • Use encodeURIComponent for special characters
  • Keep URLs readable and shareable
  • React Router v6 ranks routes by specificity

What's Next?

Congratulations! You've completed the React Router section. You now understand:

  • Setting up client-side routing
  • Creating routes and navigation
  • Programmatic navigation with useNavigate
  • Nested routes and layouts
  • Dynamic routes with parameters
  • Query strings for filtering

You can now build complete single-page applications with sophisticated routing! You know how to structure routes, handle navigation, work with dynamic data, and create shareable URLs.

You've now completed 37 out of 42 tutorials - over 88% of the React tutorial series! You have comprehensive knowledge of:

  • JSX and component fundamentals
  • State management and hooks
  • Side effects and data fetching
  • Performance optimization
  • Advanced patterns (hooks, HOCs, render props)
  • Complete routing with React Router

Only 5 tutorials remaining - you're almost at React mastery! šŸŽ‰

Learning how to work with dynamic routes and URL parameters in React Router!

Previous
Routes and Navigation
Next
Component Organization

Never Miss a New React Tutorial

Join 2,000+ developers learning React step-by-step. Get new tutorials, tips, and exclusive resources delivered to your inbox - completely FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

React Tutorials

0 of 42 completed

Your Progress0%

Topics

Getting Started

  • What is React?
  • React vs Vanilla JavaScript
  • Setting Up Your Environment
  • Your First React App

JSX Fundamentals

  • Introduction to JSX
  • JSX Expressions and Variables
  • Conditional Rendering
  • Lists and Keys
  • Styling in JSX

Components Basics

  • Function Components
  • Props
  • Children Prop
  • Props Destructuring
  • Component Composition

State Management

  • Introduction to State
  • useState Hook
  • State Updates and Re-renders
  • Multiple State Variables
  • State Best Practices

Events and Interactivity

  • Handling Events
  • Event Objects
  • Forms in React
  • Form Validation

Side Effects and Data

  • Introduction to useEffect
  • Data Fetching
  • Cleanup Functions
  • Dependency Arrays

Advanced Hooks

  • useRef Hook
  • useContext Hook
  • useMemo Hook
  • useCallback Hook

React Patterns

  • Custom Hooks
  • Higher-Order Components
  • Render Props Pattern

React Router

  • Introduction to React Router
  • Routes and Navigation
  • Dynamic Routes and Parameters

Best Practices

  • Component Organization
  • Performance Optimization
  • Error Handling
  • Testing React Components

Real World Project

  • Building a Complete App
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

Ā© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo