无法读取属性历史记录,因为它未定义,但确实如此

时间:2017-07-27 20:44:08

标签: reactjs meteor react-router react-router-dom

我收到的错误无法读取属性历史记录,但我对其进行了定义。

当我在我的客户端文件夹中的main.jsx中使用它时,它使用了该工作,但现在它停止工作。

应用程序文件位于我的导入文件夹中。

import { Router, Route, Switch, Redirect } from "react-router-dom";
import createBrowserHistory from "history/createBrowserHistory";

const history = createBrowserHistory();

// App component - represents the whole app
export class App extends Component {
  constructor(props) {
    super(props);
  }

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

        <Router history={history}>
          <Switch>
            <Route path="/" exact component={Home} />
            <Route
              path="/dashboard"
              render={() =>
                this.props.currentUser ? <Dashboard /> : <NoPermission />}
            />
            <Route path="/test" component={Test} />
            <Route component={NotFound} />
          </Switch>
        </Router>
      </div>
    );
  }
}

更多信息:

从“history / createBrowserHistory”中导入createBrowserHistory;

在该文件中,createBrowserHistory是默认导出。

export.default = createBrowserHistory;

当尝试使用BrowserRouter而不是路由器并删除历史记录const和道具时,我在控制台中出现以下错误。

modules.js:26944 Uncaught TypeError: Cannot read property 'history' of undefined
    at Link.render (modules.js?hash=b38005f7c50b72cb1ea0945090b4ba307f31282f:26944)
    at modules.js?hash=b38005f7c50b72cb1ea0945090b4ba307f31282f:18399
    at measureLifeCyclePerf (modules.js?hash=b38005f7c50b72cb1ea0945090b4ba307f31282f:17679)
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (modules.js?hash=b38005f7c50b72cb1ea0945090b4ba307f31282f:18398)
    at ReactCompositeComponentWrapper._renderValidatedComponent (modules.js?hash=b38005f7c50b72cb1ea0945090b4ba307f31282f:18425)
    at ReactCompositeComponentWrapper.performInitialMount (modules.js?hash=b38005f7c50b72cb1ea0945090b4ba307f31282f:17965)
    at ReactCompositeComponentWrapper.mountComponent (modules.js?hash=b38005f7c50b72cb1ea0945090b4ba307f31282f:17861)
    at Object.mountComponent (modules.js?hash=b38005f7c50b72cb1ea0945090b4ba307f31282f:10622)
    at ReactDOMComponent.mountChildren (modules.js?hash=b38005f7c50b72cb1ea0945090b4ba307f31282f:16977)
    at ReactDOMComponent._createInitialChildren (modules.js?hash=b38005f7c50b72cb1ea0945090b4ba307f31282f:14176)

在我的main.jsx中使用BrowserRouter时,我可以使用它。我可以更改URL,但新视图不会呈现。所以我认为历史上还有一些问题。在这种情况下,我没有定义它,但我没有收到任何错误。我怎么能检查或解决这个问题?

import React from "react";
import { Meteor } from "meteor/meteor";
import { render } from "react-dom";
import "../imports/startup/accounts-config.js";

import App from "../imports/layouts/App.jsx";
import Test from "../imports/Test.jsx";
import { BrowserRouter } from "react-router-dom";

Meteor.startup(() => {
  render(
    <BrowserRouter>
      <App />
    </BrowserRouter>,
    document.getElementById("render-target")
  );
});

进一步研究Kyle的回答,我将测试组件添加到了测试组件中。

import React, { Component } from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router";

class Test extends Component {
  static propTypes = {
    match: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired
  };

  render() {
    const { match, location, history } = this.props;

    return (
      <div>
        <p>This is a test</p>
        <p>
          You are now at {location.pathname}
        </p>
      </div>
    );
  }
}

export default withRouter(Test);

我正在导航栏组件中使用NavLinks链接到此路线。

   <NavLink to="/test" activeClassName="active">
          Test
        </NavLink>

但是,单击这些链接不会呈现测试页面。 (URL栏中的地址确实发生了变化)。当我在浏览器中按下刷新页面加载并且location.pathname显示正确的位置。

如果我删除了带路由器,功能是相同的。

我通过不使用组件来嵌套路由器来实现它。 如果有人能解释我为什么会非常感激。

import Navbar from "../components/Navbar.jsx";
import AccountsUIWrapper from "../components/AccountsUIWrapper.jsx";

//import pages
import Home from "../pages/Home.jsx";
import Dashboard from "../pages/Dashboard.jsx";
import Test from "../Test.jsx";
import NotFound from "../pages/NotFound.jsx";
import NoPermission from "../pages/NoPermission.jsx";

let currentUser = Meteor.user();

const App = () =>
  <Router>
    <div>
      <Navbar currentUser={currentUser} />

      <AccountsUIWrapper />

      <p>
        {currentUser ? currentUser._id : "current user id not found"}
      </p>

      <Switch>
        <Route exact path="/" component={Home} />
        <Route
          path="/dashboard"
          render={() => (currentUser ? <Dashboard /> : <NoPermission />)}
        />
        <Route path="/test" component={Test} />
        <Route component={NotFound} />
      </Switch>
    </div>
  </Router>;

export default App;

1 个答案:

答案 0 :(得分:1)

React Router 4已将历史记录融入其中。您可以在BrowserRouterHashRouterMemoryRouter的文档中看到history没有参数。

如果您想在React Router v4中访问历史记录,则应在您希望有权访问该组件的组件上使用withRouter HoC。withRouter({match, history, location })提供在它包装的任何组件内部。

正如您从以下代码行中看到的那样:var _createBrowserHistory = require('history/createBrowserHistory'); BrowserRouter.js中的第13行和HashRouter.js历史记录已经包含在内。它也包含在MemoryRouter.js的第9行的内存路由器中。

尝试将顶部的导入更改为import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom";,然后从history={ history }删除<Router />

编辑:请查看React Router 4的文档。这是basic example

这是一个代码的帖子,因为链接已经死了。

import React from 'react'
import {
  BrowserRouter as Router,
  Route,
  Link
} from 'react-router-dom'

const BasicExample = () => (
  <Router>
    <div>
      <ul>
        <li><Link to="/">Home</Link></li>
        <li><Link to="/about">About</Link></li>
        <li><Link to="/topics">Topics</Link></li>
      </ul>

      <hr/>

      <Route exact path="/" component={Home}/>
      <Route path="/about" component={About}/>
      <Route path="/topics" component={Topics}/>
    </div>
  </Router>
)

const Home = () => (
  <div>
    <h2>Home</h2>
  </div>
)

const About = () => (
  <div>
    <h2>About</h2>
  </div>
)

const Topics = ({ match }) => (
  <div>
    <h2>Topics</h2>
    <ul>
      <li>
        <Link to={`${match.url}/rendering`}>
          Rendering with React
        </Link>
      </li>
      <li>
        <Link to={`${match.url}/components`}>
          Components
        </Link>
      </li>
      <li>
        <Link to={`${match.url}/props-v-state`}>
          Props v. State
        </Link>
      </li>
    </ul>

    <Route path={`${match.url}/:topicId`} component={Topic}/>
    <Route exact path={match.url} render={() => (
      <h3>Please select a topic.</h3>
    )}/>
  </div>
)

const Topic = ({ match }) => (
  <div>
    <h3>{match.params.topicId}</h3>
  </div>
)

export default BasicExample