Search code examples
reactjsreact-routerjsxreact-router-domreact-bootstrap

Looping over data to create "dynamic routes" in React


I have a question to react-router-dom. Is it possible to do something like that?

I use React-Bootstrap so there some wrappers/wrapper components that could be the problem.

I try to create a dynamic route loop:

import React from "react"
import {products} from "../data/Products"
import {Route} from "react-router-dom"
import {DetailedProduct} from "../components/DetailedProduct"

export const ProductRoutesGenerator = () => {
    return (
        products.map((product => {
            return (
                <Route exact path={product.productName} component={DetailedProduct(product)}/>
            )
        })
    ))
}

and the Component should be created like that:

import {Container} from "react-bootstrap"

export const DetailedProduct = (props) => {
    return (
        <Container>
            <h1>{props.productName}</h1>
            <h3>{props.productDescription}</h3>
            <h5>{props.productPrice}</h5>
        </Container>
    )
}

Thanks for any help in advance :-)

Edit: The index.js file look like this:

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import reportWebVitals from './reportWebVitals'
import {BrowserRouter} from "react-router-dom"

ReactDOM.render(
      <React.StrictMode>
              <BrowserRouter>
                    <App/>
              </BrowserRouter>
      </React.StrictMode>,
  document.getElementById('root')
)

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint.

I just wrapped the BrowserRouter over the App. Beside that all code should be default from the create react command.

products is a JavaScript object for testing it looks like this:

export const products = [
  {
    "id": "0",
    "productName": "testProduct0",
    "productDescription": "testDescription",
    "productPrice": 10
  }
,
  {
    "id": "1",
    "productName": "testProduct1",
    "productDescription": "testDescription",
    "productPrice": 20
  }
...
ReactDOM.render(
      <React.StrictMode>
          <div>
              <h1>
                  {products[1].productName}
              </h1>
          </div>
              <BrowserRouter>
                    <App/>
              </BrowserRouter>
      </React.StrictMode>,
  document.getElementById('root')
)

renders me my product name so yes i get the value before BrowserRouter is called.


Solution

  • import React from "react"
    import {products} from "../data/Products"
    import {Route} from "react-router-dom"
    import {DetailedProduct} from "../components/DetailedProduct";
    
    export const ProductRoutesGenerator = () => {
        return (
                products.map((product) => {
                    return (
                        <Route
                            exact
                            path={'/' + product.productName}
                            key={product.id}
                            children={ <DetailedProduct product={product}/> } />
                    )
                })
        )
    }
    

    This was a journey! So I managed to render a dynamic component and link a dynamic route to it.

    I missed two things. The '/' before the product.productName and the children={} in the Route.