您不应该使用 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,或者在您的情况下,您的RouterApp 下方的该层次结构中充当BrowserRouter,它必须是层次结构中的下一个,一切else 是 BrowserRouter 的子节点,必须进入其中。

既然你永远不会在你的App 组件中使用来自react-router-domLink,请继续像这样清理它:

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 不是“在开关之上”,而是最重要的内容,包括带有下拉列表的标题。所有与路由器相关的组件,包括(LinkSwitch 等)都需要通过 context 提供 router 属性。所以你需要在组件树的某处放置一些Router(用router填充上下文)。 你能指导我在我的代码中我应该在哪里做。我正在为此苦苦挣扎。 @HussianShaik 我已经发布了几乎完整的代码。您需要先阅读一些基本的 React 教程。 @HussianShaik 另请阅读reacttraining.com/react-router/web/example/basic

以上是关于您不应该使用 react-router-dom 在路由器外部使用 Link的主要内容,如果未能解决你的问题,请参考以下文章

不变违规:您不应该在 <Router> 之外使用 withRouter() (使用最少的工作示例)

反应路由器错误:您不应该在路由器之外使用路由

不变违规:您不应该在 <Router> 之外使用 <Switch>

不变式失败:您不应该在 <Router> 之外使用 <Link>

django - 如果您不需要数据库引擎,您应该怎么做?

错误:不变量失败:您不应该在 <Router> 之外使用 <Link> 进行反应