Lewati props di Link react-router


151

Saya menggunakan react dengan react-router. Saya mencoba untuk melewatkan properti di "Link" dari 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'))
});

"Link" merender halaman tetapi tidak meneruskan properti ke tampilan baru. Di bawah ini adalah kode tampilan

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;

Bagaimana cara mengirimkan data menggunakan "Link"?

Jawaban:


134

Baris ini hilang path:

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

Seharusnya:

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

Diberikan yang berikut Link (usang v1) :

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

Terbaru sejak v4 :

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

dan di dalam withRouter(CreateIdeaView)komponen render():

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

Dari link yang Anda posting di dokumen, di bagian bawah halaman:

Diberikan rute seperti <Route name="user" path="/users/:userId"/>



Contoh kode yang diperbarui dengan beberapa contoh kueri yang dipotong:

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

pembaruan:

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

Dari panduan peningkatan dari 1.x ke 2.x:

<Link to>, onEnter, dan isActive menggunakan deskriptor lokasi

<Link to>sekarang dapat menggunakan deskriptor lokasi selain string. Query and state props tidak digunakan lagi.

// v1.0.x

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

// v2.0.0

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

// Masih valid di 2.x

<Link to="/foo"/>

Demikian juga, pengalihan dari hook onEnter sekarang juga menggunakan deskriptor lokasi.

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

Untuk komponen seperti tautan khusus, hal yang sama berlaku untuk router.isActive, sebelumnya history.isActive.

// v1.0.x

history.isActive(pathname, query, indexOnly)

// v2.0.0

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

pembaruan untuk v3 ke v4:

"dokumentasi migrasi warisan" untuk anak cucu


3
Tampaknya params tidak didukung dalam versi 2.0, karena menghitung nilai uji disimpan dalam props, itu akan menjadi sesuatu seperti <Link to = { /ideas/${this.props.testvalue}}> {this.props.testvalue} </Link>
Braulio

1
@Braulio terima kasih. Saya memperbarui jawaban saya dan menyertakan beberapa lagi dokumen untuk perbedaan <Link> antara v1 dan v2
jmunsch

4
@Braulio: cara yang benar adalah: <Link to={`/ideas/${this.props.testvalue}`}>{this.props.testvalue}</Link>, dengan tanda kutip mundur
Enoah Netzach

1
Ya, maaf, backticks hilang saat saya menempelkan kode untuk memperbaikinya.
Braulio

2
Ini berfungsi untuk saya tanpa menggunakan backticks<Link to={'/ideas/'+this.props.testvalue }>{this.props.testvalue}</Link>
svassr

103

ada cara agar Anda bisa melewatkan lebih dari satu parameter. Anda dapat meneruskan "ke" sebagai objek alih-alih 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

2
persis seperti yang kuinginkan.
gramcha

9
Jawaban ini sangat diremehkan. Tidak jelas tetapi dokumentasinya menyebutkan reacttraining.com/react-router/web/api/Link/to-object ini . Ini menyarankan untuk melewatkan data sebagai objek tunggal yang ditandai 'negara'
sErVerdevIL

14
Ini adalah jawaban terbaik untuk pertanyaan ini.
Juan Ricardo

Berurusan dengan drama terlalu lama dan ini benar-benar berhasil! V4
Mike

1
Di atribut jalur tidak boleh menjadi "/ category / 595212758daa6810cbba4104" alih-alih memetakan ke artikel ???
Camilo

38

Saya memiliki masalah yang sama untuk menampilkan detail pengguna dari aplikasi saya.

Kamu bisa melakukan ini:

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

atau

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

dan

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

untuk mendapatkan ini melalui this.props.match.params.value di kelas CreateIdeaView Anda.

Anda dapat melihat video ini yang sangat membantu saya: https://www.youtube.com/watch?v=ZBxMljq9GSE


3
Persis seperti yang dikatakan dokumentasi. Namun, saya memiliki kasus di mana DESPITE mendefinisikan Route seperti di atas, dan mengkonfigurasi LINK untuk meneruskan nilai parameter, kelas komponen React tidak memiliki nilai this.props.params yang diambil dari URL. Adakah yang tahu mengapa ini bisa terjadi? Ini seperti pengikatan rute hilang begitu saja. Render () di kelas komponen TIDAK terlibat, tetapi tidak ada data yang diteruskan ke komponen.
Peter

Tapi kemudian di contoh terakhir Anda, bagaimana Anda kemudian menarik variabel 'nilai' di komponen CreateIdeaView?
Aspen

21

adapun react-router-dom 4.xx ( https://www.npmjs.com/package/react-router-dom ) Anda dapat meneruskan parameter ke komponen untuk dirutekan melalui:

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

menghubungkan melalui (mengingat prop testValue diteruskan ke komponen terkait (misalnya komponen App di atas) rendering tautan)

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

meneruskan props ke konstruktor komponen Anda, nilai param akan tersedia melalui

props.match.params.value

Ya, ini berfungsi dengan baik <Link to = { /movie/detail/${this.state.id}} className = "btn btn-secondary btn-lg active"> Detail </Link>
Muhammad Shahzad


7

Untuk menyelesaikan jawaban di atas ( https://stackoverflow.com/a/44860918/2011818 ), Anda juga dapat mengirim objek sebaris "Ke" di dalam objek 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!"

7

Setelah install react-router-dom

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

dan ujung lain di mana rute diarahkan ulang, lakukan ini

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

5

Ketikan

Untuk pendekatan yang disebutkan seperti ini dalam banyak jawaban,

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

Saya mendapatkan kesalahan,

Objek literal hanya dapat menentukan properti yang diketahui, dan 'myProps' tidak ada di tipe 'LocationDescriptorObject | ((lokasi: Lokasi) => LocationDescriptor) '

Kemudian saya memeriksa dokumentasi resmi yang mereka sediakan stateuntuk tujuan yang sama.

Jadi ini bekerja seperti ini,

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

Dan di komponen Anda berikutnya, Anda bisa mendapatkan nilai ini sebagai berikut,

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

1
Terima kasih @gprathour
Akshay Vijay Jain


0

Rute:

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

Dan kemudian dapat mengakses parameter di komponen PageCustomer Anda seperti ini: this.props.match.params.id .

Misalnya panggilan api di komponen PageCustomer:

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

0

Pendekatan paling sederhana adalah dengan memanfaatkan to:objectdalam linkseperti yang disebutkan dalam dokumentasi:
https://reactrouter.com/web/api/Link/to-object

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

Kita dapat mengambil params (state) di atas seperti di bawah ini:

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

0

Jika Anda hanya ingin mengganti siput di rute Anda, Anda dapat menggunakan generatePathyang diperkenalkan di react-router 4.3 (2018) . Untuk hari ini, itu tidak termasuk dalam dokumentasi react-router-dom (web) , tetapi ada dalam react-router (inti) . Masalah # 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>

Itu adalah konsep yang sama yang django.urls.reversesudah lama ada.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.