【问题标题】:Pass props in Link react-router在 Link react-router 中传递道具
【发布时间】:2015-07-18 20:49:20
【问题描述】:

我正在使用 react-router。 我正在尝试在 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'))
});

“链接”呈现页面但不将属性传递给新视图。 下面是查看代码

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;

如何使用“链接”传递数据?

【问题讨论】:

    标签: javascript reactjs react-router


    【解决方案1】:

    这一行不见了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/v5 开始更新

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

    withRouter(CreateIdeaView) 组件render() 中,withRouter 高阶组件的过时用法:

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

    并在功能组件中使用useParamsuseLocation 钩子:

    const CreatedIdeaView = () => {
        const { testvalue } = useParams();
        const { query, search } = useLocation(); 
        console.log(testvalue, query.backUrl, new URLSearchParams(search).get('backUrl'))
        return <span>{testvalue} {backurl}</span>    
    }
    

    从您在文档上发布的链接到页面底部:

    给定一个类似&lt;Route name="user" path="/users/:userId"/&gt;的路由



    使用一些存根查询示例更新代码示例:

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

    #updates:

    见: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 的升级指南:

    &lt;Link to&gt;、onEnter 和 isActive 使用位置描述符

    &lt;Link to&gt; 现在除了字符串之外还可以使用位置描述符。 不推荐使用查询和状态道具。

    // 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 的更新:

    界面基本和v2一样,最好看一下react-router的CHANGES.md,因为那里是更新的地方。

    供后代使用的“遗留迁移文档”

    【讨论】:

    • 似乎 2.0 版不支持 params,假设测试值存储在 props 中,它会类似于 /ideas/${this.props.testvalue}}>{this.props.testvalue} 链接>
    • @Braulio 谢谢。我更新了我的答案,并包含了更多关于 v1 和 v2 之间 差异的文档
    • @Braulio:正确的做法是:&lt;Link to={`/ideas/${this.props.testvalue}`}&gt;{this.props.testvalue}&lt;/Link&gt;,带反引号
    • 是的,抱歉,当我粘贴要修复它的代码时,反引号丢失了。
    • 这对我有用,不使用反引号&lt;Link to={'/ideas/'+this.props.testvalue }&gt;{this.props.testvalue}&lt;/Link&gt;
    【解决方案2】:

    我在显示我的应用程序中的用户详细信息时遇到了同样的问题。

    你可以这样做:

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

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

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

    在您的 CreateIdeaView 课程中通过this.props.match.params.value 获取此信息。

    你可以看到这个对我有很大帮助的视频:https://www.youtube.com/watch?v=ZBxMljq9GSE

    【讨论】:

    • 正是文档所说的。但是,我有一个案例,尽管如上所述定义了 Route,并配置了 LINK 以传递参数值,但 React 组件类没有从 URL 中获取任何 this.props.params 值。知道为什么会发生这种情况吗?就像路由绑定完全丢失一样。组件类中的 render() 确实参与,但没有数据传递到组件中。
    • 但是在您的最后一个示例中,您如何在 CreateIdeaView 组件中提取“值”变量?
    【解决方案3】:

    对于 react-router-dom 4.x.x (https://www.npmjs.com/package/react-router-dom),你可以将参数传递给组件以路由到 via:

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

    链接方式(考虑将 testValue 属性传递给渲染链接的相应组件(例如上面的 App 组件))

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

    将道具传递给组件构造函数,值参数将通过

    获得
    props.match.params.value
    

    【讨论】:

    • 是的,效果很好/movie/detail/${this.state.id}} className="btn btn-secondary btn-lg active">详细信息
    【解决方案4】:

    有一种方法可以传递多个参数。您可以将“to”作为对象而不是字符串传递。

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

    【讨论】:

    • 正是我想要的。
    • 这个答案被低估了。这并不明显,但文档提到了这个reacttraining.com/react-router/web/api/Link/to-object。它建议将数据作为标记为“状态”的单个对象传递
    • 这是这个问题的最佳答案。
    • 处理戏剧太久了,这完全奏效了! V4
    • 在路径属性中不应该是“/category/595212758daa6810cbba4104”而不是映射到文章???
    【解决方案5】:

    路线:

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

    然后可以像这样访问您的 PageCustomer 组件中的参数:this.props.match.params.id

    例如PageCustomer组件中的一个api调用:

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

    【讨论】:

      【解决方案6】:

      安装后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);
                }
      

      【讨论】:

      • 我使用相同的方式 V5 。但是在类组件中。但不起作用
      【解决方案7】:

      要解决上面的答案 (https://stackoverflow.com/a/44860918/2011818),您还可以在 Link 对象内的“To”内发送对象。

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

      【讨论】:

        【解决方案8】:

        See this post for reference

        简单的是:

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

        现在你想访问它:

        this.props.location.state
        

        【讨论】:

        • 这个对类组件有用,对我来说它不起作用
        【解决方案9】:

        打字稿

        对于许多答案中提到的这种方法,

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

        我遇到了错误,

        对象字面量只能指定已知属性,而“myProps”在“LocationDescriptorObject |”类型中不存在。 ((location: Location) => LocationDescriptor)'

        然后我签入了official documentation,他们出于同样的目的提供了state

        所以它是这样工作的,

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

        在你的下一个组件中,你可以得到这个值,如下所示,

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

        【讨论】:

          【解决方案10】:

          最简单的方法是使用link 中的to:object,如文档中所述:
          https://reactrouter.com/web/api/Link/to-object

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

          我们可以如下检索上述参数(状态):

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

          【讨论】:

            【解决方案11】:

            对于 v5

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

            React Router Official Site

            【讨论】:

              【解决方案12】:

              如果您只是想替换路线中的 slug,您可以使用 generatePathwas introduced in react-router 4.3 (2018)。截至今天,它不包含在react-router-dom (web) documentation 中,但在react-router (core) 中。 Issue#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>
              

              这与django.urls.reverse 有一段时间的概念相同。

              【讨论】:

                【解决方案13】:

                在我的情况下,我有一个带有空道具的函数组件,这解决了它:

                <Link
                  to={{
                    pathname: `/dashboard/${device.device_id}`,
                    state: { device },
                  }}
                >
                  View Dashboard
                </Link>
                

                在你的函数组件中你应该有这样的东西:

                import { useLocation } from "react-router"
                export default function Dashboard() {
                  const location = useLocation()
                  console.log(location.state)
                  return <h1>{`Hello, I'm device ${location.state.device.device_id}!`}</h1>
                }
                

                【讨论】:

                  【解决方案14】:

                  21 年 11 月 25 日更新 感谢上面写的 alex-adestech.mx。 我能够转移整个对象并从中提取所有必要的字段 在发送组件中:

                  <Button type="submit" component={NavLink} to={{
                          pathname: '/basequestion',
                          state: {question} }}
                          variant="contained"
                          size="small">Take test</Button>
                  

                  在接收组件中:

                  import { useLocation } from "react-router"
                  const BaseQuestion = () => {
                  const location = useLocation();
                  const {description, title, images} = (location.state.question);
                  

                  【讨论】:

                    【解决方案15】:

                    我为此苦苦挣扎了几个小时,但在这个主题中没有一个答案对我有用。最后我设法在documentation 中找到了 React Router 6 的解决方案。

                    这里是完整的例子:

                    // App.js
                    
                    <BrowserRouter>
                        <Routes>
                            <Route path="/books/:bookId" element={ <BookDetails /> } />
                        </Routes>
                    </BrowserRouter>
                    
                    // BookDetails.js
                    
                    import React from "react"
                    import { useParams } from "react-router-dom"
                    
                    export default function BookPage() {
                        const params = useParams()
                        return <div> { console.log(params.bookId) } </div>
                    }
                    

                    注意useParams不能在类组件内部调用,所以必须使用函数组件(详见this答案)。

                    【讨论】:

                      猜你喜欢
                      • 2018-04-27
                      • 2021-07-31
                      • 2018-08-03
                      • 1970-01-01
                      • 2021-02-24
                      • 2018-11-20
                      • 2021-09-08
                      • 2018-05-03
                      • 1970-01-01
                      相关资源
                      最近更新 更多