【问题标题】:React router, pass data when navigating programmatically?反应路由器,以编程方式导航时传递数据?
【发布时间】:2017-06-29 15:38:36
【问题描述】:

我们可以使用

导航到不同的路径

this.props.router.push('/some/path')

有没有办法在导航时发送参数(对象)?

我还能想到其他选项,但想知道是否可以通过object

  • 我可以嵌入对象的 id 并从服务器重新获取对象 从新页面。

  • 或者我可以将对象存储在全局存储中,如 redux 存储。 (这个对象需要尽快从商店中移除。所以我认为首先将它放在那里可能不太好)

【问题讨论】:

    标签: reactjs react-router react-redux


    【解决方案1】:

    React Router 使用 location 对象。 location 对象的属性之一是 state

    this.props.router.push({
      pathname: '/other-page',
      state: {
        id: 7,
        color: 'green'
      }
    })
    

    在导航到的页面上,当前的location会被注入到路由匹配的组件中,所以你可以使用this.props.location.state访问状态。

    要记住的一点是,如果用户直接导航到页面,则不会有state,因此当数据不存在时,您仍然需要一些机制来加载数据。

    【讨论】:

    • 你有没有解决这个问题要记住的一点是,如果用户直接导航到页面,将不会有任何状态,所以你仍然需要一些机制来加载数据不存在时。
    • 还对如何优雅地处理用户直接导航到路由且未定义状态的场景感兴趣。理想情况下,它会渲染加载组件,然后仅在数据可用时将其作为道具传递给组件,以便组件行为始终可以假定所需状态在需要时存在
    • @MattMazzola 我不确定是否有“优雅”的方式,但我只会使用默认道具并使用componentWillMountcomponentDidMount 来获取数据。我已经尽可能不再使用location.state
    • @Anil 有解决方案吗?
    • 假设我们有 PageA 请求数据,当服务器响应时,PageA 重定向到 PageB 并在那里传递数据。但是用户决定直接打开PageB。这是我的解决方案(理论上,我还没有实现):当 PageB 打开时,它会检查是否有状态,如果没有,它会从会话中请求数据(无论是本地会话还是服务器会话),如果有那里也没有数据,它重定向回pageA。
    【解决方案2】:

    当前的答案已经过时了。

    反应路由器 6

    使用useNavigate 钩子:

    const navigate = useNavigate();
    navigate('/other-page', { state: { id: 7, color: 'green' } });
    

    然后,您可以通过useLocation 挂钩访问“/other-page”中的状态数据:

    const {state} = useLocation();
    const { id, color } = state; // Read values passed on state
    

    React 路由器 4 或 5

    调用history.push,并传递一个对象作为第二个参数来传递状态:

    props.history.push('/other-page', { id: 7, color: 'green' }))
    

    然后,您可以通过以下方式访问“/other-page”中的状态数据:

    props.location.state

    【讨论】:

    • 如果另一个页面推送其他状态如{size: 'big'},所有存储的状态都会被这个{size: 'big'}替换,如何在有效推送另一个状态时保持之前的状态?
    • 如何从 /other-page 访问状态数据?
    • @Suleka_28 - 我刚刚将该信息添加到答案中。
    【解决方案3】:

    你可以利用 react-router-dom 的 useHistory 钩子。

    下面的代码用于将数据传递到指定的路径,即 "/dashboard"

    let history = useHistory();
    
    history.push({
                pathname: '/dashboard',
                state:{
                    tags: 'your-value' 
                }
        });
    

    "/dashboard"你可以使用useHistory()来接收上述数据。

    以下代码供您接收数据。

    const Dashboard =()=>{
    
     let {location} = useHistory();
    
     return (<>{location.state.tags}</>)
    }
    

    【讨论】:

    • 如何使用History()来接收上述数据,能否请您添加具体代码?
    • 您可以使用 useHistory 挂钩访问您传递的状态。代码示例: let {location} = useHistory(); console.log(location.state)
    【解决方案4】:

    对于函数式组件和react-router-dom:^5.2.0,我们举个很简单的例子来说明概念

    import { useHistory } from "react-router-dom";
    
      function Sender(){ 
      
      const history = useHistory();
    
      const goToReceiver = () => {
        history.push("/receiver", { name:'Mr',age:23 });
      }
    
      return <button onClick={goToReceiver}>Go To Receiver</button>
      }
    

    现在让我们看看数据是如何到达receiver route

      import { useLocation } from "react-router-dom";
    
      function Receiver(){ 
      
      const location = useLocation();
    
        return <div>
                 <p>{location.state.name}</p>
                 <p>{location.state.age}</p>
               </div>
      }
    

    【讨论】:

      【解决方案5】:

      在反应路由器中以编程方式导航时传递查询参数

      历史对象可以通过 history.push 和 history.replace 以编程方式更改当前位置。

          history.push('/home?the=query', { some: 'state' })
      

      如果我们将历史对象作为道具传递给组件。然后我们可以使用历史对象上可用的反应路由器方法以编程方式导航。

      现在假设您将历史对象作为称为“路由器”的道具传递。因此,它将在具有基于类的语法的组件内被引用,例如:

      this.props.router
      

      使用 push 或 replace 时,您可以将 URL 路径和状态指定为单独的参数,也可以将所有内容都包含在一个类似位置的对象中作为第一个参数。

      this.props.router.push('/some/path?the=query')
      

      或者您可以使用单个类似位置的对象来指定 URL 和状态。这相当于上面的例子。

      this.props.router.push({
        pathname: '/some/path',  //path
        search: '?the=query' // query param named 'search'
      })
      

      注意 - 当然要确保 this.props.router 实际上是来自 react-router api 的历史对象。

      【讨论】:

        【解决方案6】:

        我无法使用 react-router v4+ 进行此操作。但以下确实有效:

        //I.e. add navigate using the history stack and pass context as the 2nd parameter
        this.props.history.push('/takeTest', {
          subjectsList: this.props.subjectsList.filter(f => f.isChecked === true)
        })
        

        【讨论】:

          【解决方案7】:

          如果你想在查询字符串中发送它

          this.props.router.push({
            pathname: '/payment-history',
            query: {
              email: rowData.email
            }
          })
          

          【讨论】:

            猜你喜欢
            • 2017-09-27
            • 2017-06-26
            • 2020-01-05
            • 1970-01-01
            • 2017-08-25
            • 2018-03-11
            • 2018-09-26
            相关资源
            最近更新 更多