Redirect and refresh page on form submission in React frontend

Viewed 6991

I have a form which when submitted creates a new entry in my MongoDB Database.

Upon doing this though, I want this new entry to display on my 'redirect' page. However - instead of 'refreshing' the page, it simply redirects, and the page appears the same as it did when it was last navigated away from.

So my question is, how do I re-factor my code so that on form submission the redirect also refreshes the redirect page?

Here's my submit code:

  onSubmit = (e) => {

    e.preventDefault();

    axios.post("/api/submitDebt", {
      creditCard: this.state.creditCardToggled,
      personalLoan: this.state.personalLoanToggled,
      provider: this.state.provider,
      balance: this.state.balance,
      limit: this.state.limit,
      monthly: this.state.monthly,
      interest: this.state.interest,
      borrowed: this.state.borrowed
    })

    this.props.history.push('/dashboard');
  }

I'm assuming it's because it's 'this.props.history', so it returns the original page. What's the best way for me to refactor this redirect to also reload the page on form submit?

Any help would be appreciated. Thanks!

EDIT: The dashboard component which renders the form submission. I’m doing this on mobile so hopefully works okay!

class IndividualDebts extends Component {
  constructor(props) {
    super(props)

    this.state = {
      debts: []
    }

  }

  componentDidMount() {
    axios.get("/api/fetchDebtCards")
    .then((response) => {
      this.setState({ debts: response.data })
    })
    .catch(e => {
      console.log(e)
    })
  }

  render() {

    const fetchDebts = this.state.debts.map (debt => {

      return (

       <IndividualDebtCard key={debt._id}
        picture={(`../images/${debt.provider}.jpg`)}
        provider={debt.provider}
        type={debt.creditCard === 'true' ? "Credit Card" : "Personal Loan" }
        balance={debt.balance}
        limit={debt.creditCard === 'true' ? debt.limit : debt.borrowed}
        monthly={debt.monthly}
        interest={debt.interest} />

            )
        })

    return (
      <div>
        <section className="individual-debts-section">
          <div className="individual-debts-container">

              {this.state.debts.length === 0 ?

                <div className="no-debts-container">

                <h3>There are no debts linked yet. Why not try adding one now?</h3>

                <ActionButton link="link-debt" type="button" text="Link debt" />

                </div>  : <div className="individual-debts-card-container">{fetchDebts}</div>  }

          </div>
        </section>
      </div>
    )
  }
}

export default IndividualDebts;

ANOTHER EDIT: Added my route with React Router for Dashboard component.

<Route path="/dashboard" component={Dashboard} />
3 Answers

I feel the issue is you are not waiting for the axios call (asynchronous) to finish before navigating to the dashboard. Maybe try using async/await something like:


  onSubmit = async (e) => {

    e.preventDefault();

    await axios.post("/api/submitDebt", {
      creditCard: this.state.creditCardToggled,
      personalLoan: this.state.personalLoanToggled,
      provider: this.state.provider,
      balance: this.state.balance,
      limit: this.state.limit,
      monthly: this.state.monthly,
      interest: this.state.interest,
      borrowed: this.state.borrowed
    })

    this.props.history.push('/dashboard');
  }

Alternatively, you can use then/catch block like so:


  onSubmit = (e) => {

    e.preventDefault();

    await axios.post("/api/submitDebt", {
      creditCard: this.state.creditCardToggled,
      personalLoan: this.state.personalLoanToggled,
      provider: this.state.provider,
      balance: this.state.balance,
      limit: this.state.limit,
      monthly: this.state.monthly,
      interest: this.state.interest,
      borrowed: this.state.borrowed
    })
    .then(()=> this.props.history.push('/dashboard'))
    .catch(()=> console.log("error in posting data"));

  }

If you are already loading the data on mount as you said, I see 2 possible issues:

The first one, is that you are not waiting for the async request to return before redirecting. For that purpose, simply dd an await:

onSubmit = async (e) => {

    e.preventDefault();

    await axios.post("/api/submitDebt", {
      creditCard: this.state.creditCardToggled,
      personalLoan: this.state.personalLoanToggled,
      provider: this.state.provider,
      balance: this.state.balance,
      limit: this.state.limit,
      monthly: this.state.monthly,
      interest: this.state.interest,
      borrowed: this.state.borrowed
    })

    this.props.history.push('/dashboard');
  }

The other issue is that you are not unmounting and mounting the component on each route change. Try to change your route decleration to this:

<Route path="/dashboard" render={props => <Dashboard {...props} />} />

When you use render instead of component, the route will rerender Dashboard on every pathanme change to '/dashboard', meanning your componentDidMount will run each time.

If you're using class component you can try to fetch your data when the '/dashboard' component will be mounted

componentDidMount() {
  fetchData()
}

Related