Search code examples
reactjsreact-routerreact-router-dom

Passing dynamic segment to child props using React routing


Using the React router I'd like to be able to pass a dynamic segment of the url (e.g., :id) as a property to the child element, like so:

<Routes>
    <Route path="/books/:id" element={<Book bookId={id} />} />
</Routes>

I know the following is possible:

<Routes>
    <Route path="/books/:bookId" element={<Book />} />
</Routes>

...
export default function Book(props) {
    const { bookId } = useParams();
}

But then I would lose the flexibility of creating a book component with a specific bookId on-the-fly as the bookId now suddenly is tied to the params of the URL.

Any alternatives or suggestions are welcome! Thanks!


Solution

  • you can use Context api 
    
    
    
    
    
     import React, { createContext, useContext, useState, useEffect } from 'react';
        
        const BookContext = createContext();
        
        function BookProvider(props) {
          const [bookId, setBookId] = useState(null);
          const [bookData, setBookData] = useState(null);
        
          useEffect(() => {
            if (bookId) {
              // fetch book data for the current bookId
              fetch(`/api/books/${bookId}`)
                .then(response => response.json())
                .then(data => setBookData(data));
            }
          }, [bookId]);
        
          return (
            <BookContext.Provider value={{ bookId, setBookId, bookData }}>
              {props.children}
            </BookContext.Provider>
          );
        }
        
        function useBook() {
          const context = useContext(BookContext);
        
          if (!context) {
            throw new Error('useBook must be used within a BookProvider');
          }
        
          return context;
        }
        
        export { BookProvider, useBook };