Passa gli oggetti di scena nel link reagente-router


137

Sto usando reagire con reagire-router. Sto cercando di passare la proprietà in un "Link" di reagire-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'))
});

Il "collegamento" esegue il rendering della pagina ma non passa la proprietà alla nuova vista. Di seguito è riportato il codice di visualizzazione

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;

Come posso passare i dati usando "Link"?

Risposte:


123

Manca questa riga path:

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

Dovrebbe essere:

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

Dato quanto segue Link (v1 obsoleto) :

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

Aggiornato dalla v4 :

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

e nei withRouter(CreateIdeaView)componenti render():

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

Dal link che hai pubblicato nei documenti, verso la parte inferiore della pagina:

Dato un percorso come <Route name="user" path="/users/:userId"/>



Esempio di codice aggiornato con alcuni esempi di query stub:

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

aggiornamenti:

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

Dalla guida all'aggiornamento da 1.xa 2.x:

<Link to>, onEnter e isActive utilizzano i descrittori di posizione

<Link to>ora può prendere un descrittore di posizione oltre alle stringhe. Gli oggetti di query e di stato sono obsoleti.

// v1.0.x

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

// v2.0.0

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

// Ancora valido in 2.x

<Link to="/foo"/>

Allo stesso modo, il reindirizzamento da un hook onEnter ora utilizza anche un descrittore di posizione.

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

Per i componenti personalizzati simili a collegamenti, lo stesso vale per router.isActive, precedentemente history.isActive.

// v1.0.x

history.isActive(pathname, query, indexOnly)

// v2.0.0

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

aggiornamenti da v3 a v4:

"documentazione migratoria legacy" per i posteri


3
Sembra che params non sia supportato nella versione 2.0, i valori dei test assunti sono memorizzati nei puntelli, sarebbe qualcosa come <Link to = { /ideas/${this.props.testvalue}}> {this.props.testvalue} </Link>
Braulio

1
@Braulio grazie. Ho aggiornato la mia risposta e incluso alcuni altri documenti per le differenze per <Link> tra v1 e v2
jmunsch

4
@Braulio: il modo corretto è <Link to={`/ideas/${this.props.testvalue}`}>{this.props.testvalue}</Link>
:,

1
Sì, scusa, i backtick si sono persi quando ho incollato il codice per ripararlo.
Braulio

2
Questo funziona per me senza usare i <Link to={'/ideas/'+this.props.testvalue }>{this.props.testvalue}</Link>
backtick

92

c'è un modo per passare più di un parametro. Puoi passare "a" come oggetto anziché come stringa.

// 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
esattamente quello che voglio.
gramcha,

9
Questa risposta è molto sottovalutata. Non è ovvio, ma la documentazione menziona questo reatttraining.com/react-router/web/api/Link/to-object . Consiglia di passare i dati come un singolo oggetto contrassegnato come "stato"
sErVerdevIL

14
Questa è la migliore risposta a questa domanda.
Juan Ricardo,

Ho avuto a che fare con il dramma per troppo tempo e questo ha funzionato totalmente! V4
Mike,

1
Nell'attributo path non dovrebbe essere "/ category / 595212758daa6810cbba4104" invece di mappare l'articolo ???
Camilo,

38

Ho avuto lo stesso problema per mostrare i dettagli di un utente dalla mia applicazione.

Puoi farlo:

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

o

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

e

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

per ottenerlo tramite this.props.match.params.value tua classe CreateIdeaView.

Puoi vedere questo video che mi ha aiutato molto: https://www.youtube.com/watch?v=ZBxMljq9GSE


3
Cosa dice esattamente la documentazione. Tuttavia, ho un caso in cui DESPITE definisce la route come sopra e configura LINK per passare il valore del parametro, la classe di componenti React non ha ALCUNI valori this.props.params prelevati dall'URL. Qualche idea sul perché ciò possa accadere? È come se l'associazione del percorso fosse semplicemente mancante. Il render () nella classe di componenti si impegna, ma non ci sono dati passati nel componente.
Peter,

Ma poi nel tuo ultimo esempio, come si estrae la variabile 'value' nel componente CreateIdeaView?
Aspen,

20

come per reagire-router-dom 4.xx ( https://www.npmjs.com/package/react-router-dom ) è possibile passare parametri al componente verso cui instradare tramite:

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

collegamento tramite (considerando che prop testValue viene passato al componente corrispondente (ad esempio il componente App sopra) che rende il collegamento)

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

passando oggetti di scena al costruttore del componente, il parametro valore sarà disponibile tramite

props.match.params.value


7

Dopo l'installazione react-router-dom

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

e l'altra estremità in cui il reindirizzamento del percorso lo fa

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

4

Per risolvere la risposta sopra ( https://stackoverflow.com/a/44860918/2011818 ), puoi anche inviare gli oggetti all'interno del "A" all'interno dell'oggetto Link.

<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

Dattiloscritto

Per l'approccio citato in questo modo in molte risposte,

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

Stavo ricevendo un errore,

L'oggetto letterale può specificare solo proprietà note e 'myProps' non esiste nel tipo 'LocationDescriptorObject | ((location: Location) => LocationDescriptor) '

Poi ho controllato la documentazione ufficiale che hanno fornito stateper lo stesso scopo.

Quindi ha funzionato così,

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

E nel tuo prossimo componente puoi ottenere questo valore come segue,

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

Grazie @gprathour
Akshay Vijay Jain

0

Itinerario:

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

E poi può accedere params nel componente PageCustomer in questo modo: this.props.match.params.id.

Ad esempio una chiamata API nel componente PageCustomer:

axios({
   method: 'get',
   url: '/api/customers/' + this.props.match.params.id,
   data: {},
   headers: {'X-Requested-With': 'XMLHttpRequest'}
 })
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.