Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Router id as parameter

Tags:

reactjs

router

In my app.js component i have a array called "recipes", it have to elements i like to render these elements in the router thought a id. The App component shound render it thouth the recipe component.

I have some code here, but it does not work properly. I have tried all night long, but i cant find the error. I am new to react so maybe you can see the mistake i cant.

App.js

    import React, { Component } from "react";
import "./App.css";
import Recipes from "./components/Recipes";
import { Router } from "@reach/router";
import Recipe from "./components/Recipe ";
import Nav from "./components/Nav";
import About from "./components/About";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      recipes: [
        {
          id: 1,
          title: "Drink",
          image: "https://picsum.photos/id/395/200/200"
        },
        { id: 2, title: "Pasta", image: "https://picsum.photos/id/163/200/200" }
      ]
    };
  }

  getRecipe(id) {
    //Number(id)

    return this.state.recipes.find(e => e.id === Number(id));
  }

  render() {
    return (
      <React.Fragment>
        Recipes
        {/*Sending the props from this component to the recipes component so it can be rendered there. And shown here
               <Recipes recipes={this.state.recipes}></Recipes>
          */}
        <Nav></Nav>
        <Router>
          <About path="/about"></About>
          <Recipe
            path="/recipe/:id"
            loadRecipe={id => this.getRecipe(id)}
          ></Recipe>
        </Router>
      </React.Fragment>
    );
  }
}

export default App;

Recipe.js

import React, { Component } from "react";

class Recipe extends Component {
  constructor(props) {
    super(props);

    this.state = {
      // See App.js for more details. loadRecipe is defined there.
      recipe: this.props.loadRecipe(this.props.id)
    };
  }

  render() {
    // In case the Recipe does not exists, let's make it default.
    let title = "Recipe not found";

    // If the recipe *does* exists, make a copy of title to the variable.
    if (this.state.recipe) {
      title = this.state.recipe.title;
    }

    return (
      <React.Fragment>
        <h1>The recipe:</h1>
        <p>{title}</p>
        {/* TODO: Print the rest of the recipe data here */}
      </React.Fragment>
    );
  }
}

export default Recipe;

I have these two components, i dont know whats wrong, i dont get any error.

like image 708
René Dahl Hansen Avatar asked Oct 21 '19 22:10

René Dahl Hansen


People also ask

How do I get parameters in react router?

Using React Router, when you want to create a Route that uses a URL parameter, you do so by including a : in front of the value you pass to Route 's path prop. Finally, to access the value of the URL parameter from inside of the component that is rendered by React Router, you can use React Router's useParams Hook.

How do I send ID in react JS?

To get the id of the element on click in React: Set the onClick prop on the element to a function. Access the id of the element on the currentTarget property of the event . For example, event.currentTarget.id returns the element's id .

How do you pass a parameter in react router Dom?

To pass parameters to component with React Router, we can use the useParams hook. <Route path="/details/:id" component={DetailsPage} />; to add the id parameter to our route. import { useParams } from 'react-router'; export default function DetailsPage() { const { id } = useParams(); // ... }


1 Answers

We need to add a Route component somewhere to get the functionality that you are expecting. You need to do one of two things. Either make the recipe component a Route component, or leave it as is and wrap it in a Route Component and use the render prop.

const Recipe = (props) => {
  <Route {...props}>
     // This is where your actual recipe component will live
  </Route>
}

Then you will be able to

<Recipe
  path="/recipe/:id"
  loadRecipe={this.getRecipe}>
</Recipe>

for the loadRecipe portion, you may want to just pass the function down and then use it in the Recipe component. You should get the id from the Route component.

or

  <Route path="/recipe/:id" render={()=> <Recipe passDownSomething={this.state} />} />

Once you make this change, you be able to use the trusty console.log to figure out what you are getting props wise and make the necessary adjustments.

like image 124
Austin Wolfe Avatar answered Sep 30 '22 09:09

Austin Wolfe