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
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.
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.
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.
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With