ChatGPT解决这个技术问题 Extra ChatGPT

Pass props in Link react-router

I am using react with react-router. I am trying to pass property’s in a "Link" of react-router

var React  = require('react');
var Router = require('react-router');
var CreateIdeaView = require('./components/createIdeaView.jsx');

var Link = Router.Link;
var Route = Router.Route;
var DefaultRoute = Router.DefaultRoute;
var RouteHandler = Router.RouteHandler;
var App = React.createClass({
  render : function(){
    return(
      <div>
        <Link to="ideas" params={{ testvalue: "hello" }}>Create Idea</Link>
        <RouteHandler/>
      </div>
    );
  }
});

var routes = (
  <Route name="app" path="/" handler={App}>
    <Route name="ideas" handler={CreateIdeaView} />
    <DefaultRoute handler={Home} />
  </Route>
);

Router.run(routes, function(Handler) {

  React.render(<Handler />, document.getElementById('main'))
});

The "Link" renders the page but does not pass the property to the new view. Below is the view code

var React = require('react');
var Router = require('react-router');

var CreateIdeaView = React.createClass({
  render : function(){
    console.log('props form link',this.props,this)//props not recived
  return(
      <div>
        <h1>Create Post: </h1>
        <input type='text' ref='newIdeaTitle' placeholder='title'></input>
        <input type='text' ref='newIdeaBody' placeholder='body'></input>
      </div>
    );
  }
});

module.exports = CreateIdeaView;

How can I pass data using "Link"?


j
jmunsch

This line is missing path:

<Route name="ideas" handler={CreateIdeaView} />

Should be:

<Route name="ideas" path="/:testvalue" handler={CreateIdeaView} />

Given the following Link (outdated v1):

<Link to="ideas" params={{ testvalue: "hello" }}>Create Idea</Link>

Up to date as of v4/v5:

const backUrl = '/some/other/value'
// this.props.testvalue === "hello"

// Using query
<Link to={{pathname: `/${this.props.testvalue}`, query: {backUrl}}} />

// Using search
<Link to={{pathname: `/${this.props.testvalue}`, search: `?backUrl=${backUrl}`} />
<Link to={`/${this.props.testvalue}?backUrl=${backUrl}`} />

and in the withRouter(CreateIdeaView) components render(), out dated usage of withRouter higher order component:

console.log(this.props.match.params.testvalue, this.props.location.query.backurl)
// output
hello /some/other/value

And in a functional components using the useParams and useLocation hooks:

const CreatedIdeaView = () => {
    const { testvalue } = useParams();
    const { query, search } = useLocation(); 
    console.log(testvalue, query.backUrl, new URLSearchParams(search).get('backUrl'))
    return <span>{testvalue} {backurl}</span>    
}

From the link that you posted on the docs, towards the bottom of the page:

Given a route like

Updated code example with some stubbed query examples:

// import React, {Component, Props, ReactDOM} from 'react'; // import {Route, Switch} from 'react-router'; etc etc // this snippet has it all attached to window since its in browser const { BrowserRouter, Switch, Route, Link, NavLink } = ReactRouterDOM; class World extends React.Component { constructor(props) { super(props); console.dir(props); this.state = { fromIdeas: props.match.params.WORLD || 'unknown' } } render() { const { match, location} = this.props; return (

{this.state.fromIdeas}

thing: {location.query && location.query.thing}
another1: {location.query && location.query.another1 || 'none for 2 or 3'} ); } } class Ideas extends React.Component { constructor(props) { super(props); console.dir(props); this.state = { fromAppItem: props.location.item, fromAppId: props.location.id, nextPage: 'world1', showWorld2: false } } render() { return (
  • item: {this.state.fromAppItem.okay}
  • id: {this.state.fromAppId}
  • Home 1
  • {this.state.showWorld2 &&
  • Home 2
  • } Home 3
    ); } } class App extends React.Component { render() { return ( Ideas ); } } ReactDOM.render(( ), document.getElementById('ideas'));

    #updates:

    See: https://github.com/ReactTraining/react-router/blob/0c6d51cd6639aff8a84b11d89e27887b3558ed8a/upgrade-guides/v2.0.0.md#link-to-onenter-and-isactive-use-location-descriptors

    From the upgrade guide from 1.x to 2.x: , onEnter, and isActive use location descriptors can now take a location descriptor in addition to strings. The query and state props are deprecated. // v1.0.x // v2.0.0 // Still valid in 2.x Likewise, redirecting from an onEnter hook now also uses a location descriptor. // v1.0.x (nextState, replaceState) => replaceState(null, '/foo') (nextState, replaceState) => replaceState(null, '/foo', { the: 'query' }) // v2.0.0 (nextState, replace) => replace('/foo') (nextState, replace) => replace({ pathname: '/foo', query: { the: 'query' } }) For custom link-like components, the same applies for router.isActive, previously history.isActive. // v1.0.x history.isActive(pathname, query, indexOnly) // v2.0.0 router.isActive({ pathname, query }, indexOnly)

    #updates for v3 to v4:

    https://github.com/ReactTraining/react-router/blob/432dc9cf2344c772ab9f6379998aa7d74c1d43de/packages/react-router/docs/guides/migrating.md

    https://github.com/ReactTraining/react-router/pull/3803

    https://github.com/ReactTraining/react-router/pull/3669

    https://github.com/ReactTraining/react-router/pull/3430

    https://github.com/ReactTraining/react-router/pull/3443

    https://github.com/ReactTraining/react-router/pull/3803

    https://github.com/ReactTraining/react-router/pull/3636

    https://github.com/ReactTraining/react-router/pull/3397

    https://github.com/ReactTraining/react-router/pull/3288

    The interface is basically still the same as v2, best to look at the CHANGES.md for react-router, as that is where the updates are.

    "legacy migration documentation" for posterity

    https://github.com/ReactTraining/react-router/blob/dc7facf205f9ee43cebea9fab710dce036d04f04/packages/react-router/docs/guides/migrating.md

    https://github.com/ReactTraining/react-router/blob/0c6d51cd6639aff8a84b11d89e27887b3558ed8a/upgrade-guides/v1.0.0.md

    https://github.com/ReactTraining/react-router/blob/0c6d51cd6639aff8a84b11d89e27887b3558ed8a/upgrade-guides/v2.0.0.md

    https://github.com/ReactTraining/react-router/blob/0c6d51cd6639aff8a84b11d89e27887b3558ed8a/upgrade-guides/v2.2.0.md

    https://github.com/ReactTraining/react-router/blob/0c6d51cd6639aff8a84b11d89e27887b3558ed8a/upgrade-guides/v2.4.0.md

    https://github.com/ReactTraining/react-router/blob/0c6d51cd6639aff8a84b11d89e27887b3558ed8a/upgrade-guides/v2.5.0.md


    It seems that params is not supported in version 2.0, asumming test values is stored in the props, it would be something like <Link to={/ideas/${this.props.testvalue}}>{this.props.testvalue}</Link>
    @Braulio thanks. I updated my answer and included some more of the docs for the differences for between v1 and v2
    @Braulio: the correct way is: <Link to={`/ideas/${this.props.testvalue}`}>{this.props.testvalue}</Link>, with backticks
    Yes, sorry, backticks got lost when I pasted the code going to fix it.
    This works for me without using backticks <Link to={'/ideas/'+this.props.testvalue }>{this.props.testvalue}</Link>
    S
    Shivang Patel

    there is a way you can pass more than one parameter. You can pass "to" as object instead of string.

    // your route setup
    <Route path="/category/:catId" component={Category} / >
    
    // your link creation
    const newTo = { 
      pathname: "/category/595212758daa6810cbba4104", 
      param1: "Par1" 
    };
    // link to the "location"
    // see (https://reacttraining.com/react-router/web/api/location)
    <Link to={newTo}> </Link>
    
    // In your Category Component, you can access the data like this
    this.props.match.params.catId // this is 595212758daa6810cbba4104 
    this.props.location.param1 // this is Par1
    

    exactly what I want.
    This answer is very underrated. It isn't obvious but the documentation mentions this reacttraining.com/react-router/web/api/Link/to-object. It advises to pass data as a single object marked 'state'
    This is the best answer to this question.
    In the path attribute shouldnt be "/category/595212758daa6810cbba4104" instead of mapping to article???
    This answer, while being great, won't work for V6 of react-router-dom. For that, see this answer.
    Z
    Zahidur Rahman Faisal

    I had the same problem to show an user detail from my application.

    You can do this:

    <Link to={'/ideas/'+this.props.testvalue }>Create Idea</Link>
    

    or

    <Link to="ideas/hello">Create Idea</Link>
    

    and

    <Route name="ideas/:value" handler={CreateIdeaView} />
    

    to get this via this.props.match.params.value at your CreateIdeaView class.

    You can see this video that helped me a lot: https://www.youtube.com/watch?v=ZBxMljq9GSE


    Precisely what the documentation says. However, I have a case where DESPITE defining the Route as above, and configuring the LINK to pass the parameter value, the React component class does not have ANY this.props.params values picked up from the URL. Any idea why this might happen? It is like route binding is simply missing. The render() in component class DOES engage, but there is no data passed into the component.
    But then in your last example, how do you then pull the 'value' variable in the CreateIdeaView component?
    F
    Farhan

    See this post for reference

    The simple is that:

    <Link to={{
         pathname: `your/location`,
         state: {send anything from here}
    }}
    

    Now you want to access it:

    this.props.location.state
    

    does this work for class component,for me its not working
    @lokesh yes, you need to wrap it in functional component and pass as props
    K
    Kevin K.

    as for react-router-dom 4.x.x (https://www.npmjs.com/package/react-router-dom) you can pass params to the component to route to via:

    <Route path="/ideas/:value" component ={CreateIdeaView} />
    

    linking via (considering testValue prop is passed to the corresponding component (e.g. the above App component) rendering the link)

    <Link to={`/ideas/${ this.props.testValue }`}>Create Idea</Link>
    

    passing props to your component constructor the value param will be available via

    props.match.params.value
    

    Yes it works great <Link to={/movie/detail/${this.state.id}} className="btn btn-secondary btn-lg active">Detail</Link>
    K
    Krishna Jangid

    After install react-router-dom

    <Link
        to={{
          pathname: "/product-detail",
          productdetailProps: {
           productdetail: "I M passed From Props"
          }
       }}>
        Click To Pass Props
    </Link>
    

    and other end where the route is redirected do this

    componentDidMount() {
                console.log("product props is", this.props.location.productdetailProps);
              }
    

    am using the same way V5 . But in class component .But not working
    g
    gprathour

    Typescript

    For approach mentioned like this in many answers,

    <Link
        to={{
            pathname: "/my-path",
            myProps: {
                hello: "Hello World"
            }
        }}>
        Press Me
    </Link>
    

    I was getting error,

    Object literal may only specify known properties, and 'myProps' does not exist in type 'LocationDescriptorObject | ((location: Location) => LocationDescriptor)'

    Then I checked in the official documentation they have provided state for the same purpose.

    So it worked like this,

    <Link
        to={{
            pathname: "/my-path",
            state: {
                hello: "Hello World"
            }
        }}>
        Press Me
    </Link>
    

    And in your next component you can get this value as following,

    componentDidMount() {
        console.log("received "+this.props.location.state.hello);
    }
    

    F
    FBaez51

    To work off the answer above (https://stackoverflow.com/a/44860918/2011818), you can also send the objects inline the "To" inside the Link object.

    <Route path="/foo/:fooId" component={foo} / >
    
    <Link to={{pathname:/foo/newb, sampleParam: "Hello", sampleParam2: "World!" }}> CLICK HERE </Link>
    
    this.props.match.params.fooId //newb
    this.props.location.sampleParam //"Hello"
    this.props.location.sampleParam2 //"World!"
    

    Z
    Zayne komichi

    Inside your Link component do the state

    <Link to='register' state={{name:'zayne'}}>
    

    Now to access the item in the page you went to, import useLocation

    import {useLocation} from 'react-router-dom';
    
    const Register=()=>{
    
    const location = useLocation()
    
    //store the state in a variable if you want 
    //location.state then the property or object you want
    
    const Name = location.state.name
    
    return(
      <div>
        hello my name is {Name}
      </div>
    )
    
    }
    
    

    A
    Anand Kapdi

    For v5

     <Link
      to={{
        pathname: "/courses",
        search: "?sort=name",
        hash: "#the-hash",
        state: { fromDashboard: true }
      }}
    />
    

    React Router Official Site


    a
    alex-adestech.mx

    In my case I had a function component with empty props and this solved it:

    <Link
      to={{
        pathname: `/dashboard/${device.device_id}`,
        state: { device },
      }}
    >
      View Dashboard
    </Link>
    

    In your function component you should have something like this:

    import { useLocation } from "react-router"
    export default function Dashboard() {
      const location = useLocation()
      console.log(location.state)
      return <h1>{`Hello, I'm device ${location.state.device.device_id}!`}</h1>
    }
    

    R
    RameshD

    The simplest approach would be to make use of the to:object within link as mentioned in documentation:
    https://reactrouter.com/web/api/Link/to-object

    <Link
      to={{
        pathname: "/courses",
        search: "?sort=name",
        hash: "#the-hash",
        state: { fromDashboard: true, id: 1 }
      }}
    />
    
    

    We can retrieve above params (state) as below:

    this.props.location.state // { fromDashboard: true ,id: 1 }
    

    K
    KFunk

    If you are just looking to replace the slugs in your routes, you can use generatePath that was introduced in react-router 4.3 (2018). As of today, it isn't included in the react-router-dom (web) documentation, but is in react-router (core). Issue#7679

    // myRoutes.js
    export const ROUTES = {
      userDetails: "/user/:id",
    }
    
    
    // MyRouter.jsx
    import ROUTES from './routes'
    
    <Route path={ROUTES.userDetails} ... />
    
    
    // MyComponent.jsx
    import { generatePath } from 'react-router-dom'
    import ROUTES from './routes'
    
    <Link to={generatePath(ROUTES.userDetails, { id: 1 })}>ClickyClick</Link>
    

    It's the same concept that django.urls.reverse has had for a while.


    M
    Maruf

    For v6: Attention! state should be outside from to={}

    // route setup
    <Route path="/employee-edit/:empId" element={<EmployeeEdit />} / >
    

    Link to Component

    <Link to={"/employee-edit/1"} state={{ data: employee }} > Edit </Link>
    

    or

    <Link to={{
           pathname: "/employee-edit/1",
           search: "?sort=name",
           hash: "#the-hash",
         }}
           state={{ data: employee }} > Edit </Link>
    

    Note: state is outside from to{}, but for v5:

    <Link
      to={{
        pathname: "/courses",
        search: "?sort=name",
        hash: "#the-hash",
        state: { fromDashboard: true }
      }}
    />
              
    

    Funtional component:

    import React from "react";
    import { useLocation } from "react-router-dom";
    
    const LinkTest = () => {
      const location = useLocation();
      console.log("Location", location);
      return <h1>Link Test</h1>;
    };
    
    export default LinkTest;
    

    Class Component: in order to work with hooks, we need to wrap it in functional component and pass props:

    import React, { Component } from "react";
    import { useLocation, useParams } from "react-router-dom";
    
    class LinkTestComponent extends Component {
      render() {
        console.log(this.props);
        return <h1>Link Test</h1>;
      }
    }
    
    export default () => (
      <LinkTestComponent params={useParams()} location={useLocation()} />
    );
    

    Tested with: "react-router-dom": "^6.2.2",


    e
    eanmos

    I was struggling with this for a few hours and not a single answer in this topic worked for me. Finally I managed to find a solution for React Router 6 in the documentation.

    Here is full example:

    // App.js
    
    <BrowserRouter>
        <Routes>
            <Route path="/books/:bookId" element={ <BookDetails /> } />
        </Routes>
    </BrowserRouter>
    
    // BookDetails.js
    
    import React from "react"
    import { useParams } from "react-router-dom"
    
    export default function BookPage() {
        const params = useParams()
        return <div> { console.log(params.bookId) } </div>
    }
    

    Note that useParams cannot be called inside a class component so you must use function component (see this answer for details).


    A
    Abu Shumon

    Route:

    <Route state={this.state} exact path="/customers/:id" render={(props) => <PageCustomer {...props} state={this.state} />} />
    

    And then can access params in your PageCustomer component like this: this.props.match.params.id.

    For example an api call in PageCustomer component:

    axios({
       method: 'get',
       url: '/api/customers/' + this.props.match.params.id,
       data: {},
       headers: {'X-Requested-With': 'XMLHttpRequest'}
     })
    

    c
    c-sharp-and-swiftui-devni

    Updating 25-11-21 Thanks for alex-adestech.mx who wrote above. I was able to transfer the whole object and pull out all the necessary fields from it in send-component :

    <Button type="submit" component={NavLink} to={{
            pathname: '/basequestion',
            state: {question} }}
            variant="contained"
            size="small">Take test</Button>
    

    in receive-component:

    import { useLocation } from "react-router"
    const BaseQuestion = () => {
    const location = useLocation();
    const {description, title, images} = (location.state.question);