react-router-dom v4 |上下文路由器和路由未定义

时间:2017-07-17 05:27:56

标签: reactjs hyperlink switch-statement router history

我正在运行react-router-dom 4.1.1,我遵循了多个React Router指南,甚至做了在我的计算机上运行的react-router-tutorial(尽管它使用的是react-router v2或者类似的东西) )。当我尝试在一个简单的应用程序上使用react-router-dom v4时,我遇到了很多错误。

向下滚动当前代码&错误

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory'

import App from './components/App';
import About from './components/pages/about';

const customHistory = createBrowserHistory()

ReactDOM.render((
  <Router history={customHistory}>

    <Switch>
      <Route path='/' component={App} />
      <Route path='/about' component={About}/>
    </Switch>



  </Router>
), document.getElementById('root'))

此代码单独运行并呈现我的应用程序&#39;成分

但是当我尝试添加一个&#39;链接&#39;我的应用程序组件中的组件,它不会识别它。

//App.js
import React from 'react';
import Header from './Header';
import { Link } from 'react-router-dom'

class App extends React.Component {

  render() {
    return (
      <div className="App">

        <Header className="Header" header="Header" />


        <main className='main'>
            <Link to='about'>About</Link>
        </main>

      </div>
    );
  }
}

export default App;

如果我运行这个,我收到错误:

  

TypeError:无法读取属性&#39;历史记录&#39;未定义的       在Link.render(/Users/Ryan/Desktop/df/grnd/node_modules/react-router-dom/Link.js:76:35)       at /Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:795:21       at measureLifeCyclePerf(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:75:12)       在ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext   (/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:794:25)       在ReactCompositeComponentWrapper._renderValidatedComponent(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:821:32)       在ReactCompositeComponentWrapper.performInitialMount(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:361:30)       在ReactCompositeComponentWrapper.mountComponent(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:257:21)       at Object.mountComponent(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactReconciler.js:45:35)       在ReactDOMComponent.mountChildren(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactMultiChild.js:236:44)       在ReactDOMComponent._createContentMarkup(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactDOMComponent.js:659:32)

如果我注释掉了“链接”。在App.js中的组件,该程序运行并加载“应用程序”。来自index.js。

这只是我收到的一个错误,因为我试图找出为什么我无法运行它。我也收到了错误,其中说“路线”是未定义的或者是“路由器”#39;不能嵌套孩子等等。我觉得这个问题最简单。

我在本例中使用的历史记录取自给出的示例: https://reacttraining.com/react-router/web/api/Router/history-object

3 个答案:

答案 0 :(得分:0)

首先,您使用BrowserRouter,这个创建自己的历史对象并使用此对象。因此,在您的情况下,您不应该将历史对象传递给它。实际上,在我查看BrowserRouter的代码之后,它甚至应该在你的控制台中打印一个警告。如果我是你,我会把它命名为BrowserRouter,当你阅读代码时,它会减少错误并且更清晰。

然后,在v4中,路由器只能有一个孩子。但是在Switch的情况下,它实际上只安装匹配的路由。我不确定它是否应该像这样,尝试将你的hierchy改为不同的东西,并让Router的孩子永远安装。以下是您的代码示例:

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, Route, Switch} from 'react-router-dom';

import App from './components/App';

ReactDOM.render((
  <BrowserRouter>
    <App />    
  </BrowserRouter>
), document.getElementById('root'));

然后在您的应用程序中构建您的路由逻辑,这甚至更有意义,因为您的应用程序可能是应用程序,因此它应始终存在。

//App.js
import React from 'react';
import Header from './Header';

class App extends React.Component {

  render() {

    return (
      <div className="App">
        <Header className="Header" header="Header" />
        <Switch>
          <Route exact path='/' component={Home} />
          <Route path='/about' component={About}/>
        </Switch>
      </div>
    );
  }

}

你的链接可能在我想的Header里面,或者你可能想为此构建一个特殊的Nav组件,它可能包含在Header或其他地方。现在让我们在Header中进行操作,看看它是如何工作的:

//Header.js
import React from 'react';
import {Link} from 'react-router-dom';

class Header extends React.Component {

  render() {

    return (
      <header className="header">
          <Link to='/'>Home</Link>
          <Link to='/about'>About</Link>
      </header >
    );

  }

}

答案 1 :(得分:0)

当前代码

<强> // index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './components/App';

ReactDOM.render((
  <BrowserRouter>
    <App/>
  </BrowserRouter>
), document.getElementById('root'))

<强> // App.js

import React from 'react';
import Header from './Header';
import Main from './Main';

class App extends React.Component {

  render() {
    return (
      <div className="App">

        <Header className="Header" header="Header" />

        <Main className="Main" />

      </div>
    );
  }
}

export default App;

<强> // Main.js

import React from 'react';
import { Switch, Route } from 'react-router-dom'
import Home from './Home';
import About from './About';

class Main extends React.Component {
    render() {
        return (
            <div className='Main-Container'>
                <Switch>
                    <Route exact path='/' component={Home} />
                    <Route path='/about' component={About} />
                </Switch>
            </div>
        )
    }
}

export default Main;

最近的错误

  

警告:上下文类型失败:上下文router标记为   Switch中需要,但其值为undefined。       在Switch(由Main创建)       在div(由Main创建)       在Main(由App创建)       在div(由App创建)       在App TypeError中:无法读取未定义的属性'route'       在Switch.render(/Users/Ryan/Desktop/df/grnd/node_modules/react-router/Switch.js:48:36)       at /Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:795:21       at measureLifeCyclePerf(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:75:12)       在ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext   (/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:794:25)       在ReactCompositeComponentWrapper._renderValidatedComponent(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:821:32)       在ReactCompositeComponentWrapper.performInitialMount(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:361:30)       在ReactCompositeComponentWrapper.mountComponent(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:257:21)       at Object.mountComponent(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactReconciler.js:45:35)       在ReactDOMComponent.mountChildren(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactMultiChild.js:236:44)       在ReactDOMComponent._createContentMarkup(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactDOMComponent.js:659:32)

答案 2 :(得分:0)

我发现了导致错误的原因:服务器渲染

目前,我正在使用这段代码

 //server.js

 server.get('/', (req, res) => {
      res.render('index', {
        content: ReactDOMServer.renderToString(<App />)
      });
    });

呈现给我的ejs模板

//index.ejs

<%- include('header') -%>
   <div id="root"><%- content -%></div>
<%- include('footer') -%>

当我发表评论content: ReactDOMServer.renderToString(<App />)并将其切换为类似content: 'Hello' .... <Route/><Link/>之类的内容时。