首页 文章

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

提问于
浏览
1

我正在运行 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'))

此代码单独工作并呈现我的“App”组件

但是当我尝试在我的 App 组件中添加“链接”组件时,它将无法识别它。

//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:无法读取 Link.render(/Users/Ryan/Desktop/df/grnd/node_modules/react-router-dom/Link.js:76:35)ReactCompositeComponentWrapper.mountComponent 处的 Link.render()处的 Link.render()/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 加载“应用程序”。

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

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

3 回答

  • 0

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

    然后,在 v4 中,路由器只能有 1 个子节点。但是在 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 >
        );
    
      }
    
    }
    
  • 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;
    

    最近的错误

    警告:上下文类型失败:上下文routerSwitch中标记为必需,但其值为undefined。在由(由 Main 创建)在 div 中(由 Main 创建)在 div 中(由 App 创建)在 App TypeError 中的 div(由 App 创建):无法在 Switch.render(/Users/Ryan/Desktop/df/grnd/node_modules/react-router/Switch.js:48:36)的 Switch.render(/Users/Ryan/Desktop/df/grnd/node_modules/react-router/Switch.js:48:36)读取未定义的属性'route',在 measureLifeCyclePerf(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:75:12)ReactCompositeComponentWrapper.renderValidatedComponentWithoutOwnerOrContext(_ 9)ReactCompositeComponentWrapper._renderValidatedComponent(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:821:32)at ReactCompositeComponentWrapper.performInitialMount(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:361:30)at ReactCompositeComponentWrapper.mountComponent(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactCompositeComponent.js:257:21)at 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)at ReactDOMComponent.mountChildren(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactMultiChild.js:236:44)at ReactDOMComponent._createContentMarkup(/Users/Ryan/Desktop/df/grnd/node_modules/react-dom/lib/ReactDOMComponent.js:659:32)

  • 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/> work 之类的东西。

相关问题