Next.js Discord

Discord Forum

route.push() doesn't work with browser "back" button when calling the method by dragging an element

Unanswered
West African Lion posted this in #help-forum
Open in Discord
West African LionOP
Hello! I hope you're doing well. Thank you for your time.

Context:

I have a component that is horizontally swiped from right to left to perform actions. I'm emulating the common native mobile app functionality of being able to swipe an item to perform actions.

The way this works is I've defined a minimum amount (a threshold) the swiped item is to be swiped before triggering X action.

To make the component easier to use, I'm also allowing users to click the component, which triggers the swipe via .scrollTo(); and when the element reaches the threshold I described above the defined action is performed.

Problem:

route.push() works as expected when clicking the component, but when swiping the component route.push() doesn't work as expected.

What does "doesn't work" mean? Both when clicking and when swiping the component route.push() routes to the desired page, but when swiping the component the browser "back" button doesn't go back to the previous page. It feels like route.replace() is being called; in fact, I can create the same "back" button bug when clicking the component if I replace route.push() with route.replace().

(A video of the bug has been posted in this thread)

What I've Tried:

1. Triggering route.push() by using the onScroll event
2. Triggering route.push() by using the onTouchMove event
3. Ensuring that route.push() is only being called once
4. Changing the logic behind what determines the threshold I described above

The relevant code has been posted in this thread.

Thanks again for your time!

2 Replies

West African LionOP
//Component Design

import React, { forwardRef, TouchEvent } from "react";
import styles from "./SwipeBox.module.scss";

interface Props {
  text: string;
  className?: string;
  onSwipe: () => void;
  animationOrder: number;
  onClick: () => void;
  onTouchEnd: (event: TouchEvent<HTMLDivElement>) => void;
}

const SwipeBox = forwardRef<HTMLDivElement, Props>(
  ({ text, className, animationOrder, onSwipe, onClick, onTouchEnd }, ref) => {
    return (
      <div
        onScroll={onSwipe}
        onClick={onClick}
        className={`${styles.swipeBox} ${className ? className : ""}`}
      >
        <div onTouchEnd={onTouchEnd} ref={ref} className={styles.text}>
          <h2 className="largeText">{text}</h2>
        </div>
        <div
          style={{
            animationDelay: `${animationOrder * 0.1 + 0.75}s`,
          }}
          className={styles.fillerDiv}
        />
      </div>
    );
  }
);

export default SwipeBox;



//Component Implementation

            <SwipeBox
              animationOrder={index}
              onSwipe={() => {
                setOpacity(calculatedOpacityValue);
                if (calculatedOpacityValue <= routeThreshold && !routePushed) {
                  setRoutePushed(true);
                  route.push("/the-company");
                }
              }}
              onTouchEnd={onTouchEnd}
              ref={(element) => (swipeBoxRefs.current[index] = element!)}
              onClick={() =>
                swipeBoxRefs.current[index].parentElement?.scrollTo({
                  left: swipeBoxRefs.current[index].getBoundingClientRect()
                    .width,
                  behavior: "smooth",
                })
              }
              key={index}
              text={name}
            />
West African LionOP
Here's a video of what I'm seeing. You can see that when the component is clicked the back button works, but not when the component is swiped.

In the video, I click the component first to show that route.push() works when clicking, then, after refreshing the browser, I show the bug I'm describing when swiping the component.