您不应该使用 react-router-dom 在路由器外部使用 Link
Posted
技术标签:
【中文标题】您不应该使用 react-router-dom 在路由器外部使用 Link【英文标题】:You should not use Link outside a Router using react-router-dom 【发布时间】:2018-09-11 08:41:54 【问题描述】:我正在尝试使用 react-router-dom 进行路由。我收到了一个错误,你不应该在这个之外使用。下面我附上我的代码,请检查。
index.js
import React from 'react'
import render from 'react-dom'
import Provider from 'react-redux'
import createLogger from 'redux-logger'
import App from './containers/App';
render(
<Provider>
<App/>
</Provider>,
document.getElementById('root')
)
App.js
import React from 'react';
import Dropdown from './dropdown';
import './styles.css';
import BrowserRouter as Router, Switch, Route, Link from 'react-router-dom';
import Home from './Home';
import Addatttemp from './Addatttemp';
const options = [
label: 'One' ,
label: 'Two',
label: 'Three',
label: 'Four'
]
const AgentValues=[
label: 'Add Att/temp', value:'Addatttemp' ,
label: 'Mod prof LVL',value:'Modproflvl',
label: 'Override Attr',value:'Overrideattr',
label: 'Temp',value:'temp'
]
const defaultOption = options[0]
export default class App extends React.Component
constructor (props)
super(props)
render()
return (
<div>
<div className="navbar">
<div className="align">
<div className="dropdown">
<Dropdown options=AgentValues name='Agent'/>
</div>
<div className="dropdown">
<Dropdown options=options name='Templete'/>
</div>
<div className="dropdown">
<Dropdown options=options name='Report'/>
</div>
<div className="dropdown">
<Dropdown options=options name='Search'/>
</div>
</div>
</div>
<Router>
<Switch>
<Route exact path='/' component=Home />
<Route exact path='/Agent/Addatttemp' component=Addatttemp />
</Switch>
</Router>
</div>
);
Dropdown.js
import React, Component, PropTypes from "react";
import Link from 'react-router-dom';
class dropdown extends Component
constructor (props)
super(props)
render()
var dropdownList = []
this.props.options.map((res)=>
dropdownList.push(<Link to='/'>res.label</Link>)
)
return(
<div>
<button className="dropbtn"><Link to='/'>this.props.name</Link>
</button>
<div className="dropdown-content">
dropdownList
</div>
</div>
)
export default dropdown;
Home.js
import React from 'react'
const Home = () => (
<div>
<h1>Welcome to the Tornadoes Website!</h1>
</div>
)
export default Home
Addatttemp.js
import React from 'react'
const AddTemp = () => (
<div>
<h1>Welcome to the Add att/temp!</h1>
</div>
)
export default AddTemp
像这样我写了我的代码,但是当我运行这个代码时,它会抛出像 Uncaught Error: You should not use Link outside a Router 这样的错误。我无法解决这个问题,请给我建议我做错了什么,非常感谢任何帮助。
【问题讨论】:
您似乎忘记了使用Router
,除了导入它BrowserRouter as Router
。你用棉绒吗?它应该警告您未使用的变量。
@YuryTarabanko 感谢您的回复,您能否详细说明一下,请检查我的代码并给我建议我做错了什么
我按照错误信息建议你使用Router
:)
You should not use <Link> outside a <Router>的可能重复
【参考方案1】:
如果您尝试在页面或BrowserRouter
之外的任何元素上显示Link
,您将收到此错误。此错误消息表示任何不是路由器子级的组件都不能包含任何react-router-dom
相关组件。
要在 React 中进行有效开发,您需要学习的是组件层次结构。
在您的情况下,您的父组件,层次结构顶部的那个是App
,我怎么知道?因为你在index.js
文件中这么说:
render(
<Provider>
<App/>
</Provider>,
document.getElementById('root')
)
因此,当使用react-router-dom
时,该层次结构图上的下一个应该是您的BrowserRouter
。这就是你开始失去我和 React 的地方,因为我们都在你的 App
组件中寻找 BrowserRouter
而看不到它。
这是我们现在应该看到的:
const App = () =>
return (
<div className="ui container">
<BrowserRouter>
<div>
<Route path="/" exact component=Home />
<Route path="/Agent/Addatttemp" exact component=Addattemp />
</div>
</BrowserRouter>
</div>
);
;
注意我使用了exact
关键字?我正在使用 exact
关键字,所以我不会意外匹配我即将实施的其他路线之一。
所以请继续添加您的BrowserRouter
,或者在您的情况下,您的Router
在App
下方的该层次结构中充当BrowserRouter
,它必须是层次结构中的下一个,一切else 是 BrowserRouter
的子节点,必须进入其中。
既然你永远不会在你的App
组件中使用来自react-router-dom
的Link
,请继续像这样清理它:
import BrowserRouter, Route from "react-router-dom";
一旦您按照上述操作,该错误应该会消失。
【讨论】:
【参考方案2】:正如错误消息所说,您在组件树中没有Router
。
你可以像这样在App
组件中使用它
export default class App extends React.Component
render()
return (
<Router>
<div>
<div className="navbar">
<div className="align">
<div className="dropdown">
<Dropdown options=AgentValues name='Agent'/>
</div>
<div className="dropdown">
<Dropdown options=options name='Templete'/>
</div>
<div className="dropdown">
<Dropdown options=options name='Report'/>
</div>
<div className="dropdown">
<Dropdown options=options name='Search'/>
</div>
</div>
</div>
<Switch>
<Route exact path='/' component=Home />
<Route exact path='/Agent/Addatttemp' component=Addatttemp />
</Switch>
</div>
</Router>
);
还有
你不需要只调用super
的构造函数
// this is noop
constructor (props)
super(props)
使用map
时无需推送到外部数组。
var dropdownList = this.props.options.map(res => (
<Link to='/'>res.label</Link>
))
【讨论】:
感谢您的回复,根据您的建议,我在 App.js 的开关上方添加了路由器,但我遇到了同样的错误。我在 dropdown.js 文件中为下拉列表编写了地图 @HussianShaik 不是“在开关之上”,而是最重要的内容,包括带有下拉列表的标题。所有与路由器相关的组件,包括(Link
、Switch
等)都需要通过 context
提供 router
属性。所以你需要在组件树的某处放置一些Router
(用router
填充上下文)。
你能指导我在我的代码中我应该在哪里做。我正在为此苦苦挣扎。
@HussianShaik 我已经发布了几乎完整的代码。您需要先阅读一些基本的 React 教程。
@HussianShaik 另请阅读reacttraining.com/react-router/web/example/basic以上是关于您不应该使用 react-router-dom 在路由器外部使用 Link的主要内容,如果未能解决你的问题,请参考以下文章
不变违规:您不应该在 <Router> 之外使用 withRouter() (使用最少的工作示例)
不变违规:您不应该在 <Router> 之外使用 <Switch>