上下文`router`在`Link`中被标记为必需,但它的值是`undefined`

时间:2017-06-12 12:48:52

标签: reactjs react-router

我的Link有问题。谷歌搜索了很多主题,但我没有得到正确的答案。在一个讨论中,问题出现在路由器的早期版本中,另一个是错误的组件导入问题,在第三个问题中答案甚至没有公布。

此外,'历史'

是什么

组件的版本:

"react": "^15.4",
"react-dom": "^15.4",
"react-router": "^4.1.1",
"react-router-dom": "^4.1.1"

错误是:

Warning: Failed context type: The context `router` is marked as required in `Link`,
but its value is `undefined`.

Uncaught TypeError: Cannot read property 'history' of undefined

使用Link的组件非常原始:

import React from 'react';
import { Link } from 'react-router-dom';

export default class Menu extends React.Component {

constructor(props) {
    super(props);
}

render() {
   return (
   <div>
        <ul>
            <li><Link to="/one">1</Link></li>
            <li><Link to="/two">2</Link></li>
            <li><Link to="/three">3</Link></li>
            <li><Link to="/four">4</Link></li>
        </ul>
    </div>
);
}
}

所以带路由器的组件看起来像:

import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom'

import Page1 from './Page1';
import Page2 from './Page2';
import Page3 from './Page3';
import Page4 from './Page4';

export default class Routes extends React.Component {

constructor(props) {
    super(props);
}
render() {
    return (
    <BrowserRouter text = {this.props.text}>
        <Route path = "/one"
               render={(props) => (
               <Page1 text = {this.props.text.Page1} {...props} />)} />
        <Route path = "/two"
               render={(props) => (
               <Page2 text = {this.props.text.Page2} {...props} />)} />
        <Route path = "/three"
               render={(props) => (
               <Page3 text = {this.props.text.Page3} {...props} />)} />
        <Route path = "/four"
               render={(props) => (
               <Page4 text = {this.props.text.Page4} {...props} />)} />
    </BrowserRouter>
);
}
}

App的最根本组成部分:

import Header from './pages/menu/Header';
import Routes from './Routes';

const texts = require('text.json');
sessionStorage.setItem('lang','UA');

export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
    text: texts.UA
};
this.langHandler = this.langHandler.bind(this);
}

langHandler() {
if (sessionStorage.lang === 'UA') {
    sessionStorage.setItem('lang','RU');
    this.setState({ text: texts.RU })
} else {
    sessionStorage.setItem('lang','UA');
    this.setState({ text: texts.UA })
}
}

render() {
    return (
        <div id="content">
            <Header changeLang = {this.langHandler} 
                    text = {this.state.text.header}/>
            <Routes text = {this.state.text}/>
        </div>
    );
}
}  

简而言之,关键是页面总是有一个渲染的标题,在它下面,根据所选的菜单项,渲染了相应的组件。

我将不胜感激任何建议。

3 个答案:

答案 0 :(得分:3)

您的Menu组件应嵌套在BrowserRouter组件中,以使Links在此路由器上下文中工作。

请看一下基本样本: https://reacttraining.com/react-router/web/example/basic

答案 1 :(得分:2)

您应该只在<Link>标记内使用<Router>;如果它在它之外,你会收到这个错误。

 const Links =()=>(
  <nav>
    <Link to="/">Home</Link>
    <Link to="/about">About</Link>
  </nav>  
)

const App=()=>(

          <Links/>  <==== this will throw Error
          <Router>
            <div>
              <Route path="/" component={Home} />
              <Route path="/" component={About} />
           </div>
        </Router>


    )

以下是正确的方式...

const Links =()=>(
  <nav>
    <Link to="/">Home</Link>
    <Link to="/about">About</Link>
  </nav>  
)

const App=()=>(


          <Router>
           <div>
          <Links/>  <==== this will through Error
              <Route path="/" component={Home} />
              <Route path="/" component={About} />
               </div>
        </Router>


    )

答案 2 :(得分:0)

我们假设,我们有以下内容:

import  { BrowserRouter as StaticRouter, Router, Switch, Route, Link } from 'react-router-dom';
import  createBrowserHistory from 'history/createBrowserHistory';
const   customHistory = createBrowserHistory();

然后,看起来有必要用

包装每个嵌套的链接块
<Router history={customHistory}>
    <div>
        <Link to={'/.../' + linkName1}>
            {itemName1}
        </Link>
        <Link to={'/.../' + linkName2}>
            {itemName2}
        </Link>
    </div>
</Router>