1

I have used react-router v4 for routing in my application. I have used routing to show various form like for showing apartment form, experience form, login, register etc.

Problem

When i click on apartment image, react router routes to apartment form. The route becomes /apartment. If i again then click on register button, the route do not get updated. I have to double click on register button to update the route to /register.

Here is my code

class App extends Component {
  constructor(props, context) {
    super(props, context);
    console.log('context', context);
    this.state = { show: false };
  }

  showModal(e) {
    e.preventDefault();
    this.setState({ show: true });
  }

  hideModal() {
    this.setState({ show: false });
  }

  render() {
    return (
        <div className="container-fluid">
          <Nav
            showModal={(e) => this.showModal(e)}
            hideModal={() => this.hideModal()}
            show={this.state.show}
            onHide={() => this.hideModal()}
          />
        </div>
        );
  }
}

App.contextTypes = {
  router: React.PropTypes.object
};



const Nav = (props) => (
  <Router>
    <div>
      <nav className="navbar navbar-default">
        <div className="container-fluid">
          <div className="navbar-header">
            <a className="navbar-brand" href="">
              <img
                alt="Brand"
                className="img-responsive"
                src={logo}
                role="presentation"
              />
            </a>
          </div>
          <div className="collapse navbar-collapse" id="collapse-1">
            <ul className="nav navbar-nav navbar-right nav-social-icon">
              <li className="dropdown">
                <a
                  href=""
                  className="dropdown-toggle"
                  data-toggle="dropdown"
                >
                  ES
                  <span className="caret" />
                </a>
                <ul className="dropdown-menu" style={{ color: '#000', fontWeight: 'bold' }}>
                  <li onClick={() => props.selectedLocale('en')}>
                    en
                  </li>
                  <li onClick={() => props.selectedLocale('es')}>
                    es
                  </li>
                </ul>
              </li>
              <li className="btn-group regLog">
                <button
                  className="btn btn-default"
                  onClick={props.showModal}
                >
                  <Link to={{ pathname: '/signup' }}>
                    {props.intl.formatMessage({ id: 'nav.registration.text' }) }
                  </Link>
                </button>
                <button
                  onClick={props.showModal}
                  className="btn btn-default"
                >
                  <Link to={{ pathname: '/login' }}>
                    {props.intl.formatMessage({ id: 'nav.login.text' }) }
                  </Link>
                </button>
                {props.show ?
                  <ModalForm
                    show={props.show}
                    onHide={props.onHide}
                  /> : <span />
                }
              </li>
            </ul>
          </div>
        </div>
      </nav>
    </div>
  </Router>
  );


class ModalForm extends Component {
  render() {
    const { show, onHide, intl } = this.props;
    return (
      <Router>
        <Modal
          {...this.props}
          show={show}
          onHide={onHide}
          dialogClassName="custom-modal"
        >
          <Modal.Header closeButton>
            <Link to='/login' className="logTitle">
              <Modal.Title id="contained-modal-title-lg">
                {intl.formatMessage({ id: 'nav.login.text' })}
              </Modal.Title>
            </Link>
            <Link to='/signup' className="logTitle">
              <Modal.Title id="contained-modal-title-lg">
                {intl.formatMessage({ id: 'nav.registration.text' })}
              </Modal.Title>
            </Link>
          </Modal.Header>
          <Modal.Body>
            <Match pattern='/login' component={Login} />
            <Match pattern='/signup' component={Signup} />
          </Modal.Body>
        </Modal>
      </Router>
    );
  }
}

I think its because of using onClick event and routing. How can i solve it?

UPDATE

I tried to use router context but i am getting undefined. App is a parent component and Nav is a child component. Nav component uses router while onClick functions are handled in App component where this.context.router has to be handled.

Thanks

Serenity
  • 3,884
  • 6
  • 44
  • 87
  • Which onClick event do you think is the issue? Also, where is the code for the /register route, I can't see it in your sample, did you mean the signup route? – Jayce444 Nov 25 '16 at 11:06
  • my bad, its a /signup route. – Serenity Nov 25 '16 at 11:16
  • I have updated my question. showModal is resposible for showing form in modal but my modal has two form, one for signup and one for login. So when register is clicked, a form of register should be shown in modal but if login is clicked, login form should be shown in modal. – Serenity Nov 25 '16 at 11:20

2 Answers2

0

Put the redirect on onClick function using router context ...

https://github.com/ReactTraining/react-router/blob/master/docs/API.md#routercontext

You use contextTypes from react to access router from react-router and the n use push to change url

Lucas Katayama
  • 4,445
  • 27
  • 34
0

I am also using RRv4, to handle button links as you have then I wrap the button in the link. The put the overall click handler on the link. This should call prior to the transition and if you need to prevent transition you can simply call e.preventDefault

This will maintain the declarative nature of RRv4 and prevent the need to use the experimental context feature in react.

kwelch
  • 2,370
  • 22
  • 23