11

I have used react-router v4 for routing in my application. In homepage, there is a form. When user fills up form and hits the submit button, then the action is dispatched(showResultofCar) and it should be redirected to result page which is not a child in the homepage instead it is a different page with different UI from top to bottom.

I tried to do this way but the action is not dispatched only the routing has been transitioned but shows the same homepage instead of new page(result)

index.js

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <ConnectedIntlProvider>
      <Router>
        <App />
      </Router>
    </ConnectedIntlProvider>
  </Provider>
  , document.querySelector('.app'));

app.js

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

form.js(it is a child component of banner which is a child component of app)

onSubmit = (e) => {
  e.preventDefault();
  const originwithCountry = e.target.Origen.value;
  const originwithCity = originwithCountry.split(', ')[0];
  const cityFrom = base64.encode(originwithCity);
  const startDate = (new Date(e.target.startDate.value).getTime() / 1000);
  this.props.showResultofCar(cityFrom, cityTo, startDate);
  this.context.router.transitionTo('/result');
  }

render() {
  const { focusedInput } = this.state;
  const { intl } = this.props;
  return (
    <div className="form-box text-center">
      <div className="container">
        <form className="form-inline" onSubmit={this.onSubmit}>
          <div className="form-group">
            <Field
              name='Origen'
              component={renderGeoSuggestField}
            />
          </div>
          <div className="form-group">
            <Field
              name="daterange"
              onFocusChange={this.onFocusChange}
            />
          </div>
          <Link to="/result">
          <button type="submit" className="btn btn-default buscar">
            { intl.formatMessage({ id: 'buscar.text' })}
          </button>
        </Link>
        </form>
      </div>
    </div>
  );
}

result-parent.js

class ResultParent extends Component {
  render() {
    return (
      <div className="result-page">
        <Match pattern='/result' component={Result} />
      </div>
    );
  }
}

result.js

class Result extends Component {
render() {
  return (
    <div className="result-page">
      <ResultNav />
      <Filtering />
      <Results />
    </div>
  );
}
}

actions/index.js

export function showResultofCar(cityFrom, cityTo, date) {
  return (dispatch) => {
    dispatch({ type: 'CAR_FETCH_START' });
    const token = localStorage.getItem('token');
    console.log('date', date);
    return axios.get(`${API_URL}/car/{"cityFrom":"${cityFrom}","cityTo":"${cityTo}","date":${date}}.json/null/${token}`)
      .then((response) => {
        console.log('response is', response);
        dispatch({ type: 'CAR_FETCH_SUCCESS', payload: response.data });
      })
      .catch((err) => {
        dispatch({ type: 'CAR_FETCH_FAILURE', payload: err });
      });
  };
}

My way is not working. How can i now redirect using react router v4 inside action?

Also i don't want the result to be shown inside App component(parent) because result page will be completely different with its own navbar,filtering and results option.

Note: React router v4 has been used

milan
  • 2,045
  • 2
  • 26
  • 57

1 Answers1

3

What you can do is make a redirect handler inside of your App.js:

constructor(props) {
  super(props);
  this.handleRedirect = this.handleRedirect.bind(this);
  this.handleSubmitForm = this.handleSubmitForm.bind(this);
}

handleRedirect() {
  this.props.push('/result');
}

handleSubmitForm(cityFrom, cityTo, startDate) {
  this.props.showResultofCar(cityFrom, cityTo, startDate, this.handleRedirect);
}
...

And provide your Form component with handleSubmitForm through props. This way you won't have to connect Form component to Redux dispatch actions.

Inside of your showResultofCar action you can now call this redirect handler on Promise success:

export function showResultofCar(cityFrom, cityTo, date, redirectOnSuccess) {
  ...
    .then((response) => {
      // console.log('response is', response);
      dispatch({ type: 'CAR_FETCH_SUCCESS', payload: response.data });
      redirectOnSuccess();
    })
  ...
}

I know it might not be the cleanest way but it will do the work for you.

Borna
  • 106
  • 1
  • 7