React/Router/MemoryRouter - 如何传递历史属性并在子组件中使用 push()?
Posted
技术标签:
【中文标题】React/Router/MemoryRouter - 如何传递历史属性并在子组件中使用 push()?【英文标题】:React/Router/MemoryRouter - how to pass history property and use push() in child component? 【发布时间】:2020-07-16 18:23:13 【问题描述】:我正在构建一个不希望更新浏览器中的 URL 的 React 应用程序。我没有使用“react-router-dom”,而只使用了“react-router”和 MemoryRouter (https://reacttraining.com/react-router/web/api/MemoryRouter)。 history.push() 可直接在组件语句中使用,但我希望将历史记录传递给这些主要组件的子组件,但该属性未定义。
这里是主 App.js 中的 Router 部分(组件 Home 和 ScreeningTool 可以按预期访问 this.props.history.push()):
...
import Route, MemoryRouter from "react-router";
...
<MemoryRouter>
<Route exact path="/" component=Home />
<Route path="/screening-tool" component=ScreeningTool />
</MemoryRouter>
...
Home 和 ScreeningTool 都使用子组件 AppLink 生成“链接”以在 Home 和 ScreeningTool 之间导航(注意我将“历史”作为道具传递):
Home.js:
...
<AppLink
url="/"
label="Screening Tool"
history=this.props.history
/>
...
AppLink.js:
...
<div className="pseudo-link">
<span onClick=() => this.props.history.push(this.props.url)>
this.props.label
</span>
</div>
...
上面的代码有效。但是 Home 中有子组件将创建自己的 AppLinks 和曾孙。我不想将 history 属性作为组件属性从 Parent 传递给 Child 到 GrandChild 组件,因为这看起来效率不高。我发现了以下 *** 问题,但这些选项都不适合我:
this.props.history.push works in some components and not others
react-router getting this.props.location in child components
我尝试了上面第二个 URL 中描述的较新的“userHistory”:
...
import useHistory from 'react-router';
...
render()
let history = useHistory();
return (
<div className="pseudo-link">
<span onClick=() => history.push(this.props.url)>
this.props.label
</span>
</div>
);
...
但我得到Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
。
我尝试使用此处定义的withRouter
https://reacttraining.com/react-router/web/api/withRouter,但我得到了Error: Invariant failed: You should not use <withRouter(PseudoLink) /> outside a <Router>
。
最后,this.props.history.push works in some components and not others 接受的答案以代码块 export default withRouter(connect(mapStateToProps, matchDispatchToProps)(ChildView));
结尾,但没有解释 mapStateToProps 或 matchDispatchToProps 来自哪里?
我认为问题在于我使用的是 MemoryRouter,而不是来自“reacto-router-dom”的普通/最常见的路由器。
谁能帮帮我?
【问题讨论】:
【参考方案1】:useHistory
是一个 Hook,因此它应该在功能组件中使用,而不是在基于类的组件中。
最后,this.props.history.push 的公认答案在某些组件中有效,而在其他组件中则以代码块 export default withRouter(connect(mapStateToProps, matchDispatchToProps)(ChildView)); 结尾。但没有说明 mapStateToProps 或 matchDispatchToProps 来自哪里?
-如果你不使用 redux,那么你可以使用
export default withRouter(yourComponentName);
更新
我已将 AppLink
组件更改为此,它工作正常
import React from "react";
import "./AppLink.css";
import useHistory from 'react-router';
const AppLink = props =>
const history = useHistory();
return (
<div
className="app-link-button"
onClick=() => history.push(props.url)
>
<span>props.label</span>
</div>
);
;
export default AppLink;
【讨论】:
我已将类组件更改为可以使用,但在 useHistory() 'TypeError: Cannot read property 'history' of undefined' 时仍然出现错误 至于 withRouter() 我在上面解释说我已经使用了它并且包含了错误。 @PippyLongstocking 确保所有使用withRouter
的元素都用BrowserRouter
docs 包裹起来
Ramesh,从 'react' 导入 React;从“反应路由器”导入 useHistory ;导入'./AppLink.scss'; const AppLink = (props) => let history = useHistory(); console.log('HISTORY:::', 历史);返回( history.push(props.url)> props.label ); 导出默认 AppLink;另外,我没有使用 BrowserRouter 似乎来自的 react-router-dom 。我只使用'react-router'
拉梅什,我不明白你的意思。这是一个子组件,用于显示在父组件之间导航的标签,并且当我在上面提出代码时,这些父组件由路由器包装......你能提供示例吗?以上是关于React/Router/MemoryRouter - 如何传递历史属性并在子组件中使用 push()?的主要内容,如果未能解决你的问题,请参考以下文章