如何在react-router v4中使用history.push / Link / Redirect传递参数?


216

我们如何this.props.history.push('/page')在React-Router v4中传递参数?

.then(response => {
       var r = this;
        if (response.status >= 200 && response.status < 300) {
             r.props.history.push('/template');
          });

由渲染的成分Route应该有机会获得this.props.locationthis.props.history等等。我觉得你不需要使用ref与V4了。尝试做this.props.history.push('/template');
saadq

并不是ref,指向这个是变量;this.props.history.push('/ template'); 带我到下一页,但是我想和他们一起传递道具。
IshanGarg '17

您要传递props给与路线匹配的组件吗?我认为这个GitHub线程可以解决您的问题。
saadq '17

JFYI-我删除了<a href>并添加了<Link>,它也具有发送状态的选项,可以通过this.props.location.state来访问下一页。
Manohar Reddy Poreddy

您能否将其中一项答复标记为“答案”。我相信那些花时间打字的人会很感激的。
James Poulose

Answers:


391

首先,您不需要这样做,var r = this;因为它使用的if statement是回调本身的上下文,因为您使用的是箭头功能,因此它是指React组件的上下文。

根据文档:

历史记录对象通常具有以下属性和方法:

  • 长度-(数字)历史记录堆栈中的条目数
  • action-(字符串)当前操作(PUSH,REPLACE或POP)
  • location-(对象)当前位置。可能具有以下属性:

    • pathname-(字符串)URL的路径
    • 搜索-(字符串)URL查询字符串
    • hash-(字符串)URL哈希片段
    • 状态-(字符串)特定于位置的状态,当该位置被推入堆栈时提供给例如push(path,state)。仅在浏览器和内存历史记录中可用。
  • push(path,[state])-(函数)将新条目推入历史堆栈
  • replace(path,[state])-(函数)替换历史记录堆栈上的当前条目
  • go(n)-(函数)将历史记录堆栈中的指针移动n个条目
  • goBack()-(函数)等同于go(-1)
  • goForward()-(函数)等同于go(1)
  • 块(提示)-(功能)防止导航

因此,在导航时,您可以将道具传递给历史对象,例如

this.props.history.push({
  pathname: '/template',
  search: '?query=abc',
  state: { detail: response.data }
})

或类似地对于一个Link或多个Redirect组件

<Link to={{
      pathname: '/template',
      search: '?query=abc',
      state: { detail: response.data }
    }}> My Link </Link>

然后在使用/templateroute 渲染的组件中,您可以访问像

this.props.location.state.detail

另外请记住,在使用道具中的历史记录或位置对象时,您需要将组件与相连withRouter

根据文档:

与路由器

您可以<Route>'s通过withRouter高阶组件访问历史对象的属性和最接近的 匹配项。withRouter 每当路线更改时,都会使用与<Route>render 相同的props重新渲染其组件props: { match, location, history }


3
是的,那行得通。谢谢!但不确定为什么this.props.history.push('/template',response.data)不起作用。根据的文档push(path, [state]),您不认为它应该起作用?
Sanket Patel

1
谢谢你!就我而言,我只是直接传递历史记录,因此我通过this.props.history.location.state.propName访问了我的道具
Nunchucks

@SanketPatel,您需要执行以下操作this.props.history.push('/ template',{response:response.data})
Arsalan Ahmed Quershi

导航时,可以将道具传递给历史对象,同时在状态变量中传递数据时,是否可以在新选项卡中打开路线?
Gaurav Kumar

3
那goBack()呢?使用goBack()返回时,在props.location或props.history.location中都看不到任何历史状态。使用push()向前导航可以正常工作
MariusB

40

您可以使用,

this.props.history.push("/template", { ...response }) 要么 this.props.history.push("/template", { response: response })

然后您可以/template通过以下代码从组件访问已解析的数据,

const state = this.props.location.state

阅读更多有关React Session History Management的信息


当history.push的back_url处于this.props.history.push(redirect_url,{back_url:'/ needing_url'})状态时,这种逻辑对我有用。并通过this.props.location.state.back_url到达登陆页面
德·亚达夫

24
  • 对于早期版本:

    history.push('/path', yourData);

    并在相关组件中获取数据,如下所示:

    this.props.location.state // it is equal to yourData
  • 对于较新的版本,上述方法行之有效,但是有一种新方法:

    history.push({
      pathname: '/path',
      customNameData: yourData,
    });

    并在相关组件中获取数据,如下所示:

    this.props.location.customNameData // it is equal to yourData

提示state密钥名称在较早的版本中使用,对于较新的版本,您可以使用自定义名称来传递数据,并且使用state名称不是必需的。


请分享参考,它说状态不是必需的,如果您方便的话
Akshay Vijay Jain

亲爱的@AkshayVijayJain,这是我的编码经验。我不是根据文档或参考文献来写这句话的。
AmerllicA

19

扩展解决方案(由Shubham Khatri建议)以与React钩子一起使用(从16.8开始):

package.json (always worth updating to latest packages)

{
     ...

     "react": "^16.12.0",
     "react-router-dom": "^5.1.2",

     ...
}

通过历史记录推送传递参数:

import { useHistory } from "react-router-dom";

const FirstPage = props => {
    let history = useHistory();

    const someEventHandler = event => {
       history.push({
           pathname: '/secondpage',
           search: '?query=abc',
           state: { detail: 'some_value' }
       });
    };

};

export default FirstPage;

从'react-router-dom'使用useLocation访问传递的参数:

import { useEffect } from "react";
import { useLocation } from "react-router-dom";

const SecondPage = props => {
    const location = useLocation();

    useEffect(() => {
       console.log(location.pathname); // result: '/secondpage'
       console.log(location.search); // result: '?query=abc'
       console.log(location.state.detail); // result: 'some_value'
    }, [location]);

};

非常感谢,除了您的回答,找不到更新的替代方法!
jamezrin

10

如果您需要传递URL参数

泰勒·麦金尼斯(Tyler McGinnis)在他的网站上发表了精彩的帖子解释,链接到该帖子

以下是代码示例:

  1. 在history.push组件上:

    this.props.history.push(`/home:${this.state.userID}`)

  2. 在路由器组件上,您定义路由:

    <Route path='/home:myKey' component={Home} />

  3. 在主页组件上:

componentDidMount(){
    const { myKey } = this.props.match.params
    console.log(myKey )
}

我有类似的内容,但是如果刷新页面,它将完全崩溃
rabiaasif

@rabiaasif,因为数据已不存在,您需要保留它或将其存储在本地存储中
Drew Cordano

3

不需要与路由器一起使用。这对我有用:

在您的父页面中,

<BrowserRouter>
   <Switch>
        <Route path="/routeA" render={(props)=> (
          <ComponentA {...props} propDummy={50} />
        )} />

        <Route path="/routeB" render={(props)=> (
          <ComponentB {...props} propWhatever={100} />
          )} /> 
      </Switch>
</BrowserRouter>

然后可以在ComponentA或ComponentB中访问

此道具历史

对象,包括this.props.history.push方法。


我认为您并不需要,withRouter因为您用包裹了组件BrowserRouter,其工作原理相同。
Pie'Oh'Pah

是的,您将props向下传递到包含history道具的每个组件中。
杰里米

2

要使用React 16.8+(withHooks)您可以使用这种方式

import React from 'react';
import { useHistory } from 'react-router-dom';

export default function SomeFunctionalComponent() {
let history = useHistory(); // should be called inside react component

const handleClickButton = () => {    
"funcionAPICALL"
       .then(response => {
             if (response.status >= 200 && response.status < 300) {
                 history.push('/template');
              });
}

return ( <div> Some component stuff 
    <p>To make API POST request and redirect to "/template" click a button API CALL</p>
    <button onClick={handleClickButton}>API CALL<button>
</div>)
} 

在此处获取更多信息https://reacttraining.com/react-router/web/example/auth-workflow


-12

添加信息以获取查询参数。

const queryParams = new URLSearchParams(this.props.location.search);
console.log('assuming query param is id', queryParams.get('id');

有关URLSearchParams的更多信息,请检查此链接 URLSearchParams


1
这与React Router 4完全无关。
科尔比考克斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.