简体   繁体   中英

How to create dynamic routes with react-router-dom?

I learn react and know, how to create static routes, but can't figure out with dynamic ones. Maybe someone can explain, I'll be very grateful. Let there be two components, one for rendering routes, and another as a template of a route. Maybe something wrong in the code, but hope You understand..

Here is the component to render routes:

import React, { Component } from 'react';
import axios from 'axios';
import Hero from './Hero';

class Heroes extends Component {
  constructor(props) {
    super(props);
    this.state = {
      heroes: [],
      loading: true,
      error: false,
    };
  }
  componentDidMount() {
    axios.get('http://localhost:5555/heroes')
      .then(res => {
        const heroes = res.data;
        this.setState({ heroes, loading: false });
      })
      .catch(err => { // log request error and prevent access to undefined state
        this.setState({ loading: false, error: true });
        console.error(err);
      })
  }
  render() {
    if (this.state.loading) {
      return (
        <div>
          <p> Loading... </p>
        </div>
      )
    }
    if (this.state.error || !this.state.heroes) {
      return (
        <div>
          <p> An error occured </p>
        </div>
      )
    }
    return (
      <div> 
        <BrowserRouter>
          //what should be here?
        </BrowserRouter>      
      </div>
    );
  }
}

export default Heroes;

The requested JSON looks like this:

const heroes = [
  {
    "id": 0,
    "name": "John Smith",
    "speciality": "Wizard"
  },
  {
    "id": 1,
    "name": "Crag Hack",
    "speciality": "Viking"
  },
  {
    "id": 2,
    "name": "Silvio",
    "speciality": "Warrior"
  }
];

The route component (maybe there should be props, but how to do it in the right way):

import React, { Component } from 'react';

class Hero extends Component {
  render() {
    return (
      <div>
        //what should be here?
      </div>
    );
  }
}

export default Hero;

I need something like this in browser, and every route url should be differentiaie by it's id (heroes/1, heroes/2...):

John Smith Crag Hack Silvio

Each of them:

John Smith. Wizard.

and so on...

Many thanks for any help!)

  • Use Link to dynamically generate a list of routes.
  • Use : to indicate url params, :id in the case
  • Use the match object passed as props to the rendered route component to access the url params. this.props.match.params.id
<BrowserRouter>
  /* Links */
  {heroes.map(hero => (<Link to={'heroes/' + hero.id} />)}

  /* Component */
  <Route path="heroes/:id" component={Hero} />
</BrowserRouter>

class Hero extends Component {
  render() {
    return (
      <div>
        {this.props.match.params.id}
      </div>
    );
  }
}

To do this you simply add a colon before the url part that should be dynamic. Example:

<BrowserRouter>
  /* Dynamic Component */
  <Route path="heroes/:id" component={Hero} />
</BrowserRouter>

Also you can use the useParams hook from react-router-dom to get the dynamic value for use in the page created dynamically: Example:

import { useParams } from "react"

const Hero = () => {

    const param = useParams();
    // params.id => dynamic value defined as id in route
    // e.g '/heroes/1234' -> params.id equals 1234

    return (...)
}

Update so this works for React Router v6:

React Router v6 brought some changes to the general syntax:

Before:   <Route path="heroes/:id" component={Hero} />

Now:      <Route path="heroes/:id" element={<Hero />} />


You can access params like with this.props.match anymore:


Before:   this.props.match.params.id

Now:      import {useParams} from "react-router-dom";
          const {id} = useParams();

You can now just use id as any other variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM