反应路由器,以编程方式导航时传递数据?
Posted
技术标签:
【中文标题】反应路由器,以编程方式导航时传递数据?【英文标题】:React router, pass data when navigating programmatically? 【发布时间】:2017-06-29 15:38:36 【问题描述】:我们可以使用
导航到不同的路径this.props.router.push('/some/path')
有没有办法在导航时发送参数(对象)?
我还能想到其他选项,但想知道是否可以通过object
?
我可以嵌入对象的 id 并从服务器重新获取对象 从新页面。
或者我可以将对象存储在全局存储中,如 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 我不确定是否有“优雅”的方式,但我只会使用默认道具并使用componentWillMount
或componentDidMount
来获取数据。我已经尽可能不再使用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
)
【讨论】:
以上是关于反应路由器,以编程方式导航时传递数据?的主要内容,如果未能解决你的问题,请参考以下文章
Visual Basic 以编程方式将用户名和密码传递给 https url 以使 webbrowser 显示网页并从网页下载
Vue总结第五天:vue-router (使用模块化(创建Vue组件)机制编程)router-link 标签的属性路由代码跳转懒加载路由嵌套(子路由)路由传递数据导航守卫)