简体   繁体   中英

React Router - Cannot read property 'history' of undefined

I am building a styleguide app. I have two dropdown components where a user can choose both a brand and a component - the app will then display the chosen component branded according to the selected brand. I want both of these options to be included in the URL.

The two dropdown's that are programatically changing the route. I am getting the error TypeError: Cannot read property 'history' of undefined whenever the user interacts with either dropdown.

I have a component being rendered by a route :

<Route path="/:brand/:component"
render={props => <DisplayComponent {...props} />} />

That component has two event handlers for two dropdown component that let the user select the root:

  handleComponentPick(event: any) {
    const component = event.target.value;
    this.props.history.push(`/${this.props.match.params.brand}/${component}`);
  }

  handleBrandChange = (event: any) => {
    if (event.target instanceof HTMLElement) {
      const brand = event.target.value;
      this.props.history.push(`/${brand}/${this.props.match.params.component}`);
    }
  };
  render = () => {
    return (
      <div className={"constrain-width-wide center "}>
        <ThemePicker
          component={this.props.match.params.component}
          brand={this.props.match.params.brand}
          handleBrandChange={this.handleBrandChange}
          handleComponentPick={this.handleComponentPick}
        />
        <div className="currently-selected-component" />
        <Route path="/:brand/button" component={Button} />
        <Route path="/:brand/card" component={Card} />
      </div>
    );
  };
}

I am wrapping the whole app in the Router .

ReactDOM.render(
  <Router>
    <App />
  </Router>,
  document.getElementById("root")
);```

您可以尝试以下更改handleComponentPick(event: any) { to handleComponentPick = (event: any) => {然后render = () => { to render() {希望这有效。

If you are getting this error inside a test using jest , you need to wrap your componen within a router. I am using react-testing-library , so my logic looks as follows:

import { render, cleanup } from '@testing-library/react'
import { BrowserRouter as Router } from 'react-router-dom'
import YourComponent from '../path/to/YourComponent'

// ...
describe('YourComponent component', () => {
  afterEach(cleanup)
  it('matches snapshot', () => {
    const { asFragment } = render(
      // The following will solve this issue
      <Router>
        <YourComponent />
      </Router>
    )
    expect(asFragment()).toMatchSnapshot()
  })
})

you have to pass the history like

  <Router history={browserHistory} routes={routes} />,

that way, you can use history with props to navigate.

font: https://github.com/ReactTraining/react-router/blob/v3/docs/guides/Histories.md

try to use browserHistory on you app.js, like

render(
  <Router history={browserHistory}>
    <Route path='/' component={App}>
      <IndexRoute component={Home} />
      <Route path='about' component={About} />
      <Route path='features' component={Features} />
    </Route>
  </Router>,
  document.getElementById('app')
)

that way, you are passing history for all of your another router.

We need to pass history as a prop to Router . I am expecting that you are using react router v4 aka react-router-dom .

import { createBrowserHistory } from "history";
import { Router } from "react-router-dom";


const history = createBrowserHistory();

    ... 

<Router history={history}>
     <Routes />
</Router>

Demo : https://codesandbox.io/s/yv5y905ojv

Spied on the useHistory() hook and provided the mock route data.

import routeData from 'react-router';

describe('<Component /> container tests', () => {

  beforeEach(() => {
    const mockHistory = {
      pathname: '/dashboard'
    };
    jest.spyOn(routeData, 'useHistory').mockReturnValue(mockHistory);
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM