Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redirect from redux action in react router v4

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

like image 444
milan Avatar asked Dec 03 '16 06:12

milan


People also ask

Is it possible to sync react-router with Redux?

With React Router 2+, wherever you dispatch the action, you can call browserHistory.push () (or hashHistory.push () if that’s what you use): You can do this from async action creators too if that is what you use. Show activity on this post. Have you checked out react-router-redux? This library makes it possible to sync react-router with redux.

How to redirect after action is dispatched in react-router-Dom?

while using react-router-dom version +5 you can't use useHistory hook in redux (redux toolkit). So if you want to redirect after an action is dispatched you can get your history "via useHistory () hook" in your current page (component) then pass the history along with your payload as an argument to redux.

What is navigation in react router and Redux?

Put simply, navigation refers to the ability to  move from one page to another. In this React Router and Redux tutorial, we’ll show you the nuances of navigating within your React/Redux applications and demonstrate how to do so declaratively.

How to manage history in Redux after action is dispatched?

So if you want to redirect after an action is dispatched you can get your history "via useHistory () hook" in your current page (component) then pass the history along with your payload as an argument to redux. Hence you can easily manage your history in redux after an action is dispatched like this : history.push ("somewhere)


1 Answers

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.

like image 186
Borna Avatar answered Sep 24 '22 04:09

Borna