Sean
Sean

Reputation: 139

React Router V4 Browser Back not working

I've built an app using react router v4 which isn't working as expected. The browser back button doesn't work at all. I thought it was due to some leftover state, but doesn't seem to be the case. Here is the render method:

So routing works as expected but when you click back nothing happens. Am I missing something?

<div id="redeem-root">
  <BrowserRouter basename={url.basename()}>
    <Fragment>
      <Route
        exact
        path={url.redeemHome()}
        render={() =>
          goToConfirmationPage ? (
            <Redirect to={url.confirm()} push={true} />
          ) : (
            <EnterGiftCard
              loading={this.state.loading}
              selectedCardType={this.state.selectedCardType}
              giftCardStartRedemption={this.giftCardStartRedemption}
              isSmallView={this.state.isSmallView}
              error={this.state.error}
              setActiveCardType={this.setActiveCardType}
              setPin={this.setPin}
              pin={this.state.pin}
            />
          )
        }
      />
      <Route
        exact
        path={url.confirm()}
        render={() =>
          goToThankYouPage ? (
            <Redirect to={url.thankYou()} push={true} />
          ) : (
            <ConfirmWithClickTracking
              loading={this.state.loading}
              pin={this.state.pin}
              selectedCardType={this.state.selectedCardType}
              entitlement={this.state.entitlement}
              giftCardConfirmRedemption={this.giftCardConfirmRedemption}
              error={this.state.error}
              trackingInfo={{ pageName: 'RedeemConfirm' }}
            />
          )
        }
      />

      <Route
        exact
        path={url.thankYou()}
        render={() => (
          <ThankYouWithClickTracking
            selectedCardType={this.state.selectedCardType}
            userEmailAddress={this.state.userEmailAddress}
            entitlement={this.state.entitlement}
            resetState={this.resetState}
            trackingInfo={{ pageName: 'RedeemThankYou' }}
          />
        )}
      />
    </Fragment>
  </BrowserRouter>
</div>

Upvotes: 3

Views: 3627

Answers (2)

Sean
Sean

Reputation: 139

One problem was push={true} which broke the back button. So thanks for the advice as it put me on the right track. Other issue was how I was handling state. State in the parent component dictated which page component was being rendered, so I needed a method that updated the goToConfirm state. I also had to do some fancy work to fire a method in the thankYouPage component where I bound to window.onpopstate and fired off a prop method that reset all the initial app state. Here is the final code if interested.

  render() {
const goToConfirmationPage = this.state.goToConfirmation;
const goToThankYouPage = this.state.goToThankYou;

return (
  <div id="redeem-root">
    <Switch>
        <Route
          exact path={url.redeemHome()}
          render={() => (
            goToConfirmationPage ? (
              <Redirect to={url.confirm()} push />
            ) : (
              <EnterGiftCard
                loading={this.state.loading}
                selectedCardType={this.state.selectedCardType}
                giftCardStartRedemption={this.giftCardStartRedemption}
                isSmallView={this.state.isSmallView}
                error={this.state.error}
                setActiveCardType={this.setActiveCardType}
                setPin={this.setPin}
                pin={this.state.pin}
              />
            )
          )}
        />
        <Route
          exact path={url.confirm()}
          render={() => (
            goToThankYouPage ? (
              <Redirect to={url.thankYou()} push/>
            ) : (
              <ConfirmWithClickTracking
                loading={this.state.loading}
                resetConfirmState={this.resetConfirmState}
                pin={this.state.pin}
                selectedCardType={this.state.selectedCardType}
                entitlement={this.state.entitlement}
                giftCardConfirmRedemption={this.giftCardConfirmRedemption}
                error={this.state.error}
                trackingInfo={{ pageName: 'RedeemConfirm' }}
              />
            )
          )}
        />

        <Route
          exact
          path={url.thankYou()}
          render={() => (
            <ThankYouWithClickTracking
              selectedCardType={this.state.selectedCardType}
              userEmailAddress={this.state.userEmailAddress}
              entitlement={this.state.entitlement}
              resetState={this.resetState}
              trackingInfo={{ pageName: 'RedeemThankYou' }}
            />
          )}
        />
      </Switch>
  </div>
)

}

Upvotes: 1

Tan Kim Loong
Tan Kim Loong

Reputation: 1035

It seems like doing push={true} in your Redirect component is pushing an extra stack into your BrowserHistory. Remove that and it should work

By the way, you don't need to specify push={true}. Since it's a boolean props you can just do <Redirect to={url.thankYou()} push/>

Upvotes: 1

Related Questions