deann
deann

Reputation: 796

Pass history as props to an event handler

I am creating a form which after being filled up and the submit button is clicked should navigate to another component. However, I cant seem to be able to pass history as a prop. I assume I am doing something wrong with the bindings of this but cant figure this out. Thanks.

Here is my App.js

import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import {LandingPage} from './landingPage/LandingPage';
import {ReportsPage} from './reportsPage/ReportsPage';

export class App extends React.Component {
  render() {
    return (
      <BrowserRouter >
        <Switch>
          <Route path="/" exact component={LandingPage}/>
          <Route path="/reports"
             render={() => <ReportsPage/>} 
          />
        </Switch>
      </BrowserRouter>
    );
  }
}

Here is my LandingPage.js

export class LandingPage extends React.Component {
  constructor(props){
    super(props);
    this.state = {
    ...
    this.formAnswersUpdater = this.formAnswersUpdater.bind(this)
  }

  formAnswersUpdater(e) {
    e.preventDefault()
    ...
    history.push("/reports")
  }

  render() {
    return (
      <div>
        ...
        <MyForm
          onClickOnLastInputsForm={e => this.formAnswersUpdater}
        />
      </div>
     )
   }

And here is where my event is happening. MyForm.js

export class MyForm extends React.Component {
render() {
  return(
    ...
    <Route render={({history}) => (
      <button className="uk-button uk-button-primary uk-width-1-1@s"
              style={{backgroundColor:'#41f44f',
                      color:'#666', margin: 0}}
              id='buttonSliders'
              /*if done here it works*/
              /*onClick={() => {history.push("/reports")}}*/
              /*However if passed to the event handler it does not*/
              onClick={() => {this.props.onClickOnLastInputsForm}}
      >
        ClickMe!
      </button>
    )}/>
  )

My react-router-dom version is: "^4.2.2"

Upvotes: 1

Views: 2091

Answers (2)

deann
deann

Reputation: 796

Ok, here is how I handled the issue.

Instead of exporting the LandingPage component, I wrapped it in withRouter function and then exported it.

class LandingPage extends React.Component {
  constructor(props){
    super(props);
    this.state = {
    ...
    this.formAnswersUpdater = this.formAnswersUpdater.bind(this)
  }

  formAnswersUpdater(e) {
    e.preventDefault()
    ...
    //added this.props. here
    this.props.history.push("/reports")
  }



render() {
    return (
      <div>
        ...
        <MyForm
          onClickOnLastInputsForm={e => this.formAnswersUpdater}
        />
      </div>
     )
}
// wrapped it with withRouter
export default withRouter(LandingPage)

And then in MyForm component I just called the eventHandler.

export class MyForm extends React.Component {
render() {
  return(
    ...
      <button className="uk-button uk-button-primary uk-width-1-1@s"
              style={{backgroundColor:'#41f44f',
                      color:'#666', margin: 0}}
              id='buttonSliders'
              onClick={this.props.onClickOnLastInputsForm()}
      >
        ClickMe!
      </button>
  )

Upvotes: 2

Andrew
Andrew

Reputation: 7545

I don't know if this will solve all of your problems, but I see something important missing in your LandingPage render function

onClickOnLastInputsForm={e => this.formAnswersUpdater}

You forgot to pass in your argument: e

onClickOnLastInputsForm={e => this.formAnswersUpdater(e)}

Make sure you add this on MyForm as well. You forgot it there as well. Do you get any other errors after fixing those?

edit: After some inspection of the docs, it looks like the typical use of react-router-dom has a different pattern than what you have. Most common pattern with route handling is to have a root set of routes and use Link from the npm package to navigate. I only see history and its derivatives in the docs for react-router. I'm aware that react-router-dom is a derivative of react-router, but I think if you follow the normal patterns for React, it'll be a lot easier for you in the future when you're debugging.

A nice article on it. It even has a sample app using it: https://medium.com/@pshrmn/a-simple-react-router-v4-tutorial-7f23ff27adf

Upvotes: 0

Related Questions