Передача реквизита в Link реакции-роутера

137

Я использую реагирую с реактивом-роутером. Я пытаюсь передать свойства в "Link" реакции-маршрутизатора

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

«Ссылка» отображает страницу, но не передает свойство новому представлению. Ниже приведен код вида

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;

Как я могу передать данные, используя «Ссылку»?

вишал атмакури
источник

Ответы:

123

Эта строка отсутствует path:

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

Должно быть:

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

Учитывая следующее Link (устаревший v1) :

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

Начиная с v4 :

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

и в withRouter(CreateIdeaView)компонентах render():

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

От ссылки, которую вы разместили в документации, к нижней части страницы:

Учитывая маршрут как <Route name="user" path="/users/:userId"/>



Обновленный пример кода с некоторыми примерами заглушки:

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

обновления:

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

Из руководства по обновлению с 1.x до 2.x:

<Link to>, onEnter и isActive используют дескрипторы местоположения

<Link to>Теперь можно взять дескриптор местоположения в дополнение к строкам. Запрос и состояние реквизита устарели.

// v1.0.x

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

// v2.0.0

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

// Действует в 2.x

<Link to="/foo"/>

Аналогично, перенаправление с хука onEnter теперь также использует дескриптор местоположения.

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

Для пользовательских компонентов, подобных ссылкам, то же самое относится к router.isActive, ранее history.isActive.

// v1.0.x

history.isActive(pathname, query, indexOnly)

// v2.0.0

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

Обновления для v3 до v4:

«Документация по миграции» для потомков

jmunsch
источник
3
Похоже, что params не поддерживается в версии 2.0, итоговые значения теста хранятся в подпорках, это будет что-то вроде <Link to = { /ideas/${this.props.testvalue}}> {this.props.testvalue} </ Link>
Браулио
1
@Braulio спасибо. Я обновил свой ответ и включил еще несколько документов для различий для <Link> между v1 и v2
jmunsch
4
@Braulio: правильный путь: <Link to={`/ideas/${this.props.testvalue}`}>{this.props.testvalue}</Link>с
кавычками
1
Да, извините, галочки потерялись, когда я вставил код, собирающийся это исправить.
Браулио
2
Это работает для меня без использования обратных <Link to={'/ideas/'+this.props.testvalue }>{this.props.testvalue}</Link>
галочек
93

есть способ передать более одного параметра. Вы можете передать «в» как объект вместо строки.

// 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
именно то, что я хочу.
Грамча
9
Этот ответ очень недооценен. Это неочевидно, но в документации упоминается это responsetraining.com/react-router/web/api/Link/to-object . Рекомендуется передавать данные как один объект, помеченный как «состояние»
sErVerdevIL
14
Это лучший ответ на этот вопрос.
Хуан Рикардо
Занимался драмой слишком долго, и это сработало! V4
Майк
1
В атрибуте пути не должно быть "/ category / 595212758daa6810cbba4104" вместо сопоставления со статьей ???
Камило
38

У меня была такая же проблема, чтобы показать детали пользователя из моего приложения.

Ты можешь сделать это:

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

или

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

и

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

чтобы получить это через this.props.match.params.value ваш класс CreateIdeaView.

Вы можете посмотреть это видео, которое мне очень помогло: https://www.youtube.com/watch?v=ZBxMljq9GSE

Алессандр Франса
источник
3
Именно то, что сказано в документации. Однако у меня есть случай, когда DESPITE, определяющий маршрут, как указано выше, и настраивающий LINK для передачи значения параметра, класс компонента React не имеет ЛЮБЫХ значений this.props.params, взятых из URL. Есть идеи, почему это может произойти? Это как привязка маршрута просто отсутствует. Функция render () в классе компонента ОБЯЗАНА, но данные не передаются в компонент.
Питер
Но затем, в последнем примере, как вы извлекаете переменную 'value' в компоненте CreateIdeaView?
Аспен
20

Что касается response-router-dom 4.xx ( https://www.npmjs.com/package/react-router-dom ), вы можете передать параметры компоненту для маршрутизации через:

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

связывание через (учитывая, что свойство testValue передается соответствующему компоненту (например, вышеуказанному компоненту приложения), отображающему ссылку)

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

передавая реквизиты в ваш конструктор компонента, значение параметра будет доступно через

props.match.params.value
Кевин К.
источник
7

После установки react-router-dom

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

и другой конец, где маршрут перенаправлен сделать это

componentDidMount() {
            console.log("product props is", this.props.location.productdetailProps);
          }
Кришна Кумар Джангид
источник
4

Чтобы отработать ответ, приведенный выше ( https://stackoverflow.com/a/44860918/2011818 ), вы также можете отправить объекты внутри «To» внутри объекта 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!"
FBaez51
источник
3

Машинопись

За подход, упомянутый во многих ответах,

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

Я получаю ошибку,

Литерал объекта может указывать только известные свойства, а myProps не существует в типе LocationDescriptorObject | ((location: Location) => LocationDescriptor) '

Затем я проверил официальную документацию, которую они предоставили stateдля той же цели.

Так это сработало,

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

И в следующем компоненте вы можете получить это значение следующим образом:

componentDidMount() {
    console.log("received "+this.props.location.state.hello);
}
gprathour
источник
Спасибо @gprathour
Акшай Виджай Джайн
0

Маршрут:

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

И тогда может получить доступ к Params в компоненте PageCustomer , как это: this.props.match.params.id.

Например, вызов API в компоненте PageCustomer:

axios({
   method: 'get',
   url: '/api/customers/' + this.props.match.params.id,
   data: {},
   headers: {'X-Requested-With': 'XMLHttpRequest'}
 })
Абу Шумон
источник