Übergeben Sie Requisiten im Link React-Router


137

Ich benutze React mit React-Router. Ich versuche, Eigenschaften in einem "Link" des React-Routers zu übergeben

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'))
});

Der "Link" rendert die Seite, übergibt die Eigenschaft jedoch nicht an die neue Ansicht. Unten ist der Ansichtscode

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;

Wie kann ich Daten mit "Link" übergeben?

Antworten:


123

Diese Zeile fehlt path:

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

Sollte sein:

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

Angesichts der folgenden Link (veraltete v1) :

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

Aktuell ab v4 :

const backUrl = '/some/other/value'
// this.props.testvalue === "hello"
<Link to={{pathname: `/${this.props.testvalue}`, query: {backUrl}}} />

und in den withRouter(CreateIdeaView)Komponenten render():

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

Von dem Link, den Sie in den Dokumenten gepostet haben, zum Ende der Seite:

Gegeben eine Route wie <Route name="user" path="/users/:userId"/>



Aktualisiertes Codebeispiel mit einigen Beispielen für gestoppelte Abfragen:

// 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 (
      <React.Fragment>
        <h2>{this.state.fromIdeas}</h2>
        <span>thing: 
          {location.query 
            && location.query.thing}
        </span><br/>
        <span>another1: 
        {location.query 
          && location.query.another1 
          || 'none for 2 or 3'}
        </span>
      </React.Fragment>
    );
  }
}

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 (
      <React.Fragment>
          <li>item: {this.state.fromAppItem.okay}</li>
          <li>id: {this.state.fromAppId}</li>
          <li>
            <Link 
              to={{
                pathname: `/hello/${this.state.nextPage}`, 
                query:{thing: 'asdf', another1: 'stuff'}
              }}>
              Home 1
            </Link>
          </li>
          <li>
            <button 
              onClick={() => this.setState({
              nextPage: 'world2',
              showWorld2: true})}>
              switch  2
            </button>
          </li>
          {this.state.showWorld2 
           && 
           <li>
              <Link 
                to={{
                  pathname: `/hello/${this.state.nextPage}`, 
                  query:{thing: 'fdsa'}}} >
                Home 2
              </Link>
            </li> 
          }
        <NavLink to="/hello">Home 3</NavLink>
      </React.Fragment>
    );
  }
}


class App extends React.Component {
  render() {
    return (
      <React.Fragment>
        <Link to={{
          pathname:'/ideas/:id', 
          id: 222, 
          item: {
              okay: 123
          }}}>Ideas</Link>
        <Switch>
          <Route exact path='/ideas/:id/' component={Ideas}/>
          <Route path='/hello/:WORLD?/:thing?' component={World}/>
        </Switch>
      </React.Fragment>
    );
  }
}

ReactDOM.render((
  <BrowserRouter>
    <App />
  </BrowserRouter>
), document.getElementById('ideas'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router-dom/4.3.1/react-router-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/4.3.1/react-router.min.js"></script>

<div id="ideas"></div>

Aktualisierung:

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

Aus der Upgrade-Anleitung von 1.x auf 2.x:

<Link to>, onEnter und isActive verwenden Standortbeschreibungen

<Link to>kann jetzt zusätzlich zu Zeichenfolgen einen Standortdeskriptor verwenden. Die Abfrage und Status Requisiten sind veraltet.

// v1.0.x.

<Link to="/foo" query={{ the: 'query' }}/>

// v2.0.0

<Link to={{ pathname: '/foo', query: { the: 'query' } }}/>

// Immer noch gültig in 2.x.

<Link to="/foo"/>

Ebenso wird beim Umleiten von einem onEnter-Hook jetzt auch ein Standortdeskriptor verwendet.

// 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' } })

Für benutzerdefinierte linkartige Komponenten gilt das Gleiche für router.isActive, zuvor history.isActive.

// v1.0.x.

history.isActive(pathname, query, indexOnly)

// v2.0.0

router.isActive({ pathname, query }, indexOnly)

Updates für v3 bis v4:

"Legacy Migration Documentation" für die Nachwelt


3
Es scheint, dass params in Version 2.0 nicht unterstützt werden, da summierende Testwerte in den Requisiten gespeichert sind. Es wäre so etwas wie <Link to = { /ideas/${this.props.testvalue}}> {this.props.testvalue} </ Link>
Braulio

1
@ Hydraulio danke. Ich habe meine Antwort aktualisiert und einige weitere Dokumente für die Unterschiede für <Link> zwischen v1 und v2
hinzugefügt

4
@Braulio: der richtige Weg ist : <Link to={`/ideas/${this.props.testvalue}`}>{this.props.testvalue}</Link>, mit Backticks
Enoah Netzach

1
Ja, sorry, Backticks gingen verloren, als ich den Code einfügte, um das Problem zu beheben.
Braulio

2
Dies funktioniert für mich ohne Backticks<Link to={'/ideas/'+this.props.testvalue }>{this.props.testvalue}</Link>
Svassr

91

Es gibt eine Möglichkeit, mehr als einen Parameter zu übergeben. Sie können "to" als Objekt anstelle einer Zeichenfolge übergeben.

// 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

2
genau das was ich will.
Gramcha

8
Diese Antwort wird sehr unterschätzt. Es ist nicht offensichtlich, aber in der Dokumentation wird dieses Reacttraining.com/react-router/web/api/Link/to-object erwähnt . Es wird empfohlen, Daten als einzelnes Objekt mit der
Bezeichnung

13
Dies ist die beste Antwort auf diese Frage.
Juan Ricardo

Ich habe mich viel zu lange mit Drama beschäftigt und das hat total funktioniert! V4
Mike

1
Im Pfad sollte das Attribut nicht "/ category / 595212758daa6810cbba4104" sein, anstatt dem Artikel zuzuordnen ???
Camilo

38

Ich hatte das gleiche Problem, ein Benutzerdetail aus meiner Anwendung anzuzeigen.

Du kannst das:

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

oder

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

und

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

um dies über this.props.match.params.valueIhre CreateIdeaView-Klasse zu erhalten.

Sie können dieses Video sehen, das mir sehr geholfen hat: https://www.youtube.com/watch?v=ZBxMljq9GSE


3
Genau das, was in der Dokumentation steht. Es gibt jedoch einen Fall, in dem trotz der Definition der Route wie oben und der Konfiguration des LINKs zur Übergabe des Parameterwerts in der React-Komponentenklasse KEINE this.props.params-Werte von der URL übernommen wurden. Irgendeine Idee, warum das passieren könnte? Es ist, als ob die Routenbindung einfach fehlt. Das render () in der Komponentenklasse wird aktiviert, es werden jedoch keine Daten an die Komponente übergeben.
Peter

Aber wie können Sie dann in Ihrem letzten Beispiel die Variable 'value' in der CreateIdeaView-Komponente abrufen?
Aspen

20

Für React-Router-Dom 4.xx ( https://www.npmjs.com/package/react-router-dom ) können Sie Parameter an die Komponente übergeben, an die weitergeleitet werden soll:

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

Verknüpfung über (unter Berücksichtigung, dass testValue prop an die entsprechende Komponente (z. B. die obige App-Komponente) übergeben wird, die die Verknüpfung rendert)

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

Wenn Sie Requisiten an Ihren Komponentenkonstruktor übergeben, ist der Wertparameter über verfügbar

props.match.params.value


7

Nach der Installation react-router-dom

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

und an einem anderen Ende, an dem die Route umgeleitet wird, tun Sie dies

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

4

Um die obige Antwort ( https://stackoverflow.com/a/44860918/2011818 ) zu bearbeiten , können Sie die Objekte auch inline mit dem "An" im Link-Objekt senden.

<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!"

3

Typoskript

Für einen Ansatz, der in vielen Antworten so erwähnt wird,

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

Ich habe einen Fehler bekommen,

Das Objektliteral darf nur bekannte Eigenschaften angeben, und 'myProps' ist im Typ 'LocationDescriptorObject | nicht vorhanden ((location: Location) => LocationDescriptor) '

Dann habe ich die offiziellen Unterlagen eingecheckt, die sie statefür denselben Zweck bereitgestellt haben .

Also hat es so funktioniert,

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

Und in Ihrer nächsten Komponente können Sie diesen Wert wie folgt erhalten:

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

Vielen Dank an @gprathour
Akshay Vijay Jain

0

Route:

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

Und dann können Sie wie folgt auf Parameter in Ihrer PageCustomer-Komponente zugreifen : this.props.match.params.id.

Zum Beispiel ein API-Aufruf in der PageCustomer-Komponente:

axios({
   method: 'get',
   url: '/api/customers/' + this.props.match.params.id,
   data: {},
   headers: {'X-Requested-With': 'XMLHttpRequest'}
 })
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.