Passer les accessoires dans Link react-router

137

J'utilise react avec react-router. J'essaye de passer la propriété dans un "lien" de 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'))
});

Le "Lien" rend la page mais ne transmet pas la propriété à la nouvelle vue. Ci-dessous le code de vue

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;

Comment puis-je transmettre des données en utilisant "Link"?

vishal atmakuri
la source

Réponses:

123

Cette ligne est manquante path:

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

Devrait être:

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

Compte tenu de ce qui suit Link (v1 obsolète) :

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

À jour à partir de la v4 :

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

et dans les withRouter(CreateIdeaView)composants render():

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

À partir du lien que vous avez publié sur les documents, vers le bas de la page:

Étant donné un itinéraire comme <Route name="user" path="/users/:userId"/>



Exemple de code mis à jour avec quelques exemples de requêtes stubbed:

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

mises à jour:

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

À partir du guide de mise à niveau de 1.x à 2.x:

<Link to>, onEnter et isActive utilisent des descripteurs d'emplacement

<Link to>peut désormais prendre un descripteur d'emplacement en plus des chaînes. Les accessoires de requête et d'état sont obsolètes.

// v1.0.x

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

// v2.0.0

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

// Toujours valide en 2.x

<Link to="/foo"/>

De même, la redirection à partir d'un hook onEnter utilise désormais également un descripteur d'emplacement.

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

Pour les composants de type lien personnalisés, il en va de même pour router.isActive, précédemment history.isActive.

// v1.0.x

history.isActive(pathname, query, indexOnly)

// v2.0.0

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

mises à jour de la v3 à la v4:

"documentation sur la migration héritée" pour la postérité

Jmunsch
la source
3
Il semble que les paramètres ne soient pas pris en charge dans la version 2.0, comme les valeurs de test sont stockées dans les accessoires, ce serait quelque chose comme <Link to = { /ideas/${this.props.testvalue}}> {this.props.testvalue} </Link>
Braulio
1
@Braulio merci. J'ai mis à jour ma réponse et inclus un peu plus de documentation pour les différences pour <Link> entre v1 et v2
jmunsch
4
@Braulio: la bonne façon est <Link to={`/ideas/${this.props.testvalue}`}>{this.props.testvalue}</Link>:, avec backticks
Enoah Netzach
1
Oui, désolé, les backticks se sont perdus lorsque j'ai collé le code pour le réparer.
Braulio
2
Cela fonctionne pour moi sans utiliser de backticks<Link to={'/ideas/'+this.props.testvalue }>{this.props.testvalue}</Link>
svassr
92

il existe un moyen de transmettre plusieurs paramètres. Vous pouvez passer "à" comme objet au lieu de chaîne.

// 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
Chetan Sisodiya
la source
2
exactement ce que je veux.
gramcha
9
Cette réponse est très sous-estimée. Ce n'est pas évident mais la documentation mentionne ce reacttraining.com/react-router/web/api/Link/to-object . Il conseille de transmettre les données en tant qu'objet unique marqué `` état ''
sErVerdevIL
14
C'est la meilleure réponse à cette question.
Juan Ricardo
Je suis confronté au drame depuis trop longtemps et cela a totalement fonctionné! V4
Mike
1
Dans l'attribut de chemin ne devrait pas être "/ category / 595212758daa6810cbba4104" au lieu de mapper à l'article ???
Camilo
38

J'ai eu le même problème pour afficher un détail d'utilisateur de mon application.

Tu peux le faire:

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

ou

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

et

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

pour l'obtenir via this.props.match.params.value votre classe CreateIdeaView.

Vous pouvez voir cette vidéo qui m'a beaucoup aidé: https://www.youtube.com/watch?v=ZBxMljq9GSE

Alessander França
la source
3
Exactement ce que dit la documentation. Cependant, j'ai un cas où MALGRÉ la définition de la Route comme ci-dessus et la configuration du LINK pour passer la valeur du paramètre, la classe de composant React n'a AUCUNE valeur this.props.params prélevée à partir de l'URL. Une idée de pourquoi cela pourrait arriver? C'est comme si la liaison d'itinéraire manquait tout simplement. Le render () dans la classe de composant S'engage, mais aucune donnée n'est transmise au composant.
Peter
Mais ensuite, dans votre dernier exemple, comment extraire la variable «valeur» dans le composant CreateIdeaView?
Aspen
20

comme pour react-router-dom 4.xx ( https://www.npmjs.com/package/react-router-dom ), vous pouvez passer des paramètres au composant à router via:

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

liaison via (considérant que la prop testValue est passée au composant correspondant (par exemple, le composant App ci-dessus) rendant le lien)

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

en passant des accessoires à votre constructeur de composants, le paramètre de valeur sera disponible via

props.match.params.value
Kevin K.
la source
13

Voir cet article pour référence

Le simple est que:

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

Vous voulez maintenant y accéder:

this.props.location.state
Farhan
la source
7

Après l'installation react-router-dom

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

et l'autre extrémité où la route est redirigée, faites ceci

componentDidMount() {
            console.log("product props is", this.props.location.productdetailProps);
          }
Krishna Kumar Jangid
la source
4

Pour travailler sur la réponse ci-dessus ( https://stackoverflow.com/a/44860918/2011818 ), vous pouvez également envoyer les objets en ligne le «À» à l'intérieur de l'objet Lien.

<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!"
FBaez51
la source
3

Manuscrit

Pour l'approche mentionnée comme celle-ci dans de nombreuses réponses,

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

Je recevais une erreur

L'objet littéral ne peut spécifier que des propriétés connues, et «myProps» n'existe pas dans le type «LocationDescriptorObject | ((location: Location) => LocationDescriptor) '

Ensuite, j'ai vérifié la documentation officielle qu'ils ont fourniestate dans le même but.

Donc ça a fonctionné comme ça,

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

Et dans votre prochain composant, vous pouvez obtenir cette valeur comme suit,

componentDidMount() {
    console.log("received "+this.props.location.state.hello);
}
gprathour
la source
Merci @gprathour
Akshay Vijay Jain
0

Route:

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

Et peut alors accéder params dans votre composant PageCustomer comme ceci: this.props.match.params.id.

Par exemple, un appel d'API dans le composant PageCustomer:

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