React URI params in functional components

25,739

Solution 1

If you wrap your component (functional or class) in withRouter, your props extend the RouteComponentProps from react-router, which can be corretly set up, just as you did in the seconds example. To access the correct params, you have to extend the props like this:

RouteComponentProps<{ id?: string; }>

This will let typescript know, that you have a match props with an field id, which is optional. You can now access them type safe with props.match.params.id. You can also extend that, to fit your other parameters. Hope this helps. Happy coding.

Solution 2

//use useParams 
import { useParams } from 'react-router-dom';

const params = useParams()

// yuo can find all params from here
console.log(params)

Solution 3

As Domino987 said in their answer, the solution is to simply extend the props interface:

import * as React from "react";
import {withRouter, RouteComponentProps} from "react-router";

function MyComponent(props: MyComponentProps) {
    const query = props.location.search;

    return <span>Query: {query}, myField: {props.myField}</span>;
}

interface MyComponentProps extends RouteComponentProps {
    myField: string;
}

export default withRouter(MyComponent);

Solution 4

For Functional component, use below code

Include:

import { BrowserRouter as Router, Switch, Route, Redirect, useLocation
} from 'react-router-dom'

Define function in your functional component:

const useQuery= () => {
       return new URLSearchParams(useLocation().search);
}

Call function:

let query = useQuery();

Get the query get parameters:

console.log("Get data==>",query.get('logout'));
URL: http://localhost:8080/login?logout=false

Output:

Get data==> false
Share:
25,739

Related videos on Youtube

Snackoverflow
Author by

Snackoverflow

I would rather dive deep into intricate solutions than add the next grid to the admin panel.

Updated on April 18, 2021

Comments

  • Snackoverflow
    Snackoverflow about 3 years

    What would be the correct approach to reading URI parameters from a functional React component?

    In JavaScript, if the component is a direct child of a Switch, we could do:

    function MyComponent(props) {
        const query = props.location.search;
        // ...
    }
    

    If the component is not a direct child of a Switch, we could use a class:

    class MyComponent extends Component<RouteComponentProps> {
        render() {
            const query = this.props.location.search;
            // ...
        }
    }
    
    export default withRouter(MyComponent);
    

    What about a functional component in strict TypeScript?

    We want the location property (and any other, if there are more) to be available and predefined by some interface or type, but supplied by React, not the user of the component. An ugly hack would be to define the interface ourselves and then expect it to actually be that way.

  • Snackoverflow
    Snackoverflow almost 5 years
    I have found the solution. Now when I am reading this, I believe it points somewhat to the same direction. The key is to extend your interface with RouteComponentProps and it seems to work. Though, I don't actually understand the id?: string part. Is that some property that is missing by default from RouteComponentProps interface? That's why we need to add it manually?
  • Domino987
    Domino987 almost 5 years
    Because you can create a route like you want to. Since the match params can be anything you want like : <Route path='/analytics/:id?' component={this.renderAnalytics} /> , you have to tell typescript, what you set it to. It could also be abalyticID, or selectedAnalytic.
  • Snackoverflow
    Snackoverflow almost 5 years
    Ahhh, yes. I just read about match from reacttraining.com/react-router/core/api/match Did not know about it before.
  • gnganapath
    gnganapath over 3 years
    const query = props.match.params.id ==> id is my query param. it accessible in functional component. Thanks a lot;
  • gnganapath
    gnganapath over 3 years
    Just realized, react16.13 can map in Route <Route path="/update-employee/:id" exact component= {UpdateEmployee} /> the in child fuctional componet we pass props and get the props.match.params.{yourVarble}. It's working
  • Snackoverflow
    Snackoverflow about 3 years
    Thank you for the answer, looks cool, I want to try it
  • Naveen Attri
    Naveen Attri about 3 years
    Even if we don't make useQuery, this solution making use of useLocation is still more elegant compared to withRouter stuff.
  • Brian Tompsett - 汤莱恩
    Brian Tompsett - 汤莱恩 about 3 years
    While this code snippet may solve the problem, it doesn't explain why or how it answers the question. Please include an explanation for your code, as that really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. You can use the edit button to improve this answer to get more votes and reputation!