Skip to content

Instantly share code, notes, and snippets.

@verticalgrain
Last active April 26, 2022 15:37
Show Gist options
  • Save verticalgrain/195468e69f2ac88f3d9573d285b09764 to your computer and use it in GitHub Desktop.
Save verticalgrain/195468e69f2ac88f3d9573d285b09764 to your computer and use it in GitHub Desktop.
React Router V4 Redirect after form submission
import React, { Component } from 'react'
import { Redirect } from 'react-router'
export default class ContactForm extends Component {
constructor () {
super();
this.state = {
fireRedirect: false
}
}
submitForm = (e) => {
e.preventDefault()
this.setState({ fireRedirect: true })
}
render () {
const { from } = this.props.location.state || '/'
const { fireRedirect } = this.state
return (
<div>
<form onSubmit={this.submitForm}>
<button type="submit">Submit</button>
</form>
{fireRedirect && (
<Redirect to={from || '/thank-you'}/>
)}
</div>
)
}
}
@jsjoeio
Copy link

jsjoeio commented Jan 1, 2018

I've tried this multiple times and I can't seem to get it to work. Any suggestions?

//AppForm.js
import React, { Component } from 'react';
import { BrowserRouter as Redirect } from 'react-router-dom';

class AppForm extends Component {
    constructor(props) {    
        super(props);
        this.state = { ... link: '', name: '', fireRedirect: false };
        this.handleSubmit = this.handleSubmit.bind(this);
    }
    handleSubmit(e) {
        e.preventDefault();
        ...
        this.setState({ ... fireRedirect: true });
    }
    render() {
        const fireRedirect = this.state;
        return (
            <div>
                <form style={style.commentForm} onSubmit={this.handleSubmit}>
                    
                </form>
                {fireRedirect && (
                    <Redirect to={"/"}/>
                )}
            </div>
        )
    }
}

export default AppForm;

@capy-pl
Copy link

capy-pl commented Jan 2, 2018

really helps a lot here.

@michaelfindlater
Copy link

Saved me some time refactoring code. Cheers.

@ahummel25
Copy link

ahummel25 commented Feb 3, 2018

In initial example, where is this.props.location being set? Where is that prop value coming from? I don't have that on my props when trying to use this example.

I get this error every time using original example Uncaught Error: You should not use <Redirect> outside a <Router>

@cmendesfirmino
Copy link

Many thanks

@guilhermeventura
Copy link

jjprevite commented on 1 Jan
I've tried this multiple times and I can't seem to get it to work. Any suggestions?

//AppForm.js
import React, { Component } from 'react';
import { BrowserRouter as Redirect } from 'react-router-dom';

class AppForm extends Component {
constructor(props) {
super(props);
this.state = { ... link: '', name: '', fireRedirect: false };
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
...
this.setState({ ... fireRedirect: true });
}
render() {
const fireRedirect = this.state;
return (


            </form>
            {fireRedirect && (
                <Redirect to={"/"}/>
            )}
        </div>
    )
}

}

export default AppForm;

The problem is with this line:
import { BrowserRouter as Redirect } from 'react-router-dom';

You're using an alias, basically giving the name Redirect to the BrowserRouter component :)

You need to do this instead:

import { Redirect } from 'react-router-dom';

OR if u need both:

import { BrowserRouter , Redirect } from 'react-router-dom';

@AlexeyHussar
Copy link

Thanks!! Very useful, helps a lot!!

@Dev-Dipesh
Copy link

@jjprevite Check your error logs, most of the time you will find the solution there. The problem for you is this line:

const fireRedirect = this.state;

While it should be:

const {fireRedirect} = this.state;

@fatosmorina
Copy link

A really great gist. Thank you very much.

@rupachandran92
Copy link

thanks it saved me lot of time.

@mateosantosdev
Copy link

Thanks!!!!

@bagazdoswiadczen
Copy link

Thanks 😄 🔝

@nahomypuente
Copy link

thanks!!!

@cal0610
Copy link

cal0610 commented May 10, 2018

If you are using redux-saga to manage your side effects and api calls, I would suggest doing this in the saga.

Why? Keeps your component clean and you don't need to keep a state in your component just for the redirect.

I.e. Steps:

  1. Submit a form
  2. Dispatch action
  3. Saga listens for the action, and calls the api
  4. On success, redirect to wherever you want.

Code:

function* createInvoice(action) {
  try {
    const response = yield call(axios.post, COMMAND_INVOICES_URL, action.data);
    yield put(invoiceCreated());
    yield put(push(`/invoice/${response.data}`));
  } catch (err) {
    yield put(invoiceFailed(err));
  }
}

@BronwynHarris
Copy link

thank you :)

@Themringshaiza
Copy link

@verticalgrain thank you so much.much applauded.

@atulnitrr
Copy link

verticalgrain@ thanks a lot it saved my day

@lucasalberto
Copy link

Thanks! Very clean solution!

@ggf-84
Copy link

ggf-84 commented May 12, 2019

Thank you!!!!

@irfanonk
Copy link

irfanonk commented Apr 23, 2020

I think this is another solution. Since there are there elemnet that router provides which are match, location adn history, we may push any route to history. considering rerouting after submiting a form:
{history} = this.props <button onClick={this.onFormSubmit(formValues, history)} )> Submit <button/> ( onFormSubmit(formValues, history) { database.post(formValues) (some codes) history.push('/') } )

@IvoTsochev
Copy link

nice one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment