skip to Main Content

On each page I have a header that has a ‘Back’ button with functionality to go back to the previous page. Function handleGoBack():

import React from 'react';
import { Button, Typography } from "@material-tailwind/react";
import { ArrowLeftIcon } from "@heroicons/react/20/solid";
import { useNavigate } from 'react-router-dom';

const PageHeader = ({ title }) => {
  const navigate = useNavigate();

  const handleGoBack = () => {
    // Redirects the user back to the previous page they came from
    navigate(-1);
  };

  return (
    <div className="h-24 flex flex-col">
      <div>
        <Button variant="text" className="flex gap-2" onClick={handleGoBack}>
          <ArrowLeftIcon strokeWidth={2} className="w-4 h-4" />
          Back
        </Button>
      </div>

      <div>
        <Typography variant="h3" color="black" className="mb-2 mx-4">
          {title}
        </Typography>
      </div>
      <hr
        className="my-2 border-green-100"
        style={{ boxShadow: "0px 2px 4px rgba(0, 0, 0, 0.2)" }}
      />
    </div>
  );
};

export default PageHeader;

Also, in most pages I have a scrollToTop() function that actually loads the next page from the beginning (from 0,0 coordinates):

function scrollToTop() {
  window.scrollTo(0, 0);
}

Let’s see this example (link to "/records", with onClick={scrollToTop):

import {
  Card,
  CardBody,
  Typography,
  Button,
  ListItem,
} from "@material-tailwind/react";
import {
  ArrowLongRightIcon,
  ChevronRightIcon
} from "@heroicons/react/24/outline";
import React from "react";
import { Link } from "react-router-dom";

export default function LastRecordsCard() {
  function scrollToTop() {
    window.scrollTo(0, 0);
  }

  return (
    <Card className="w-full shadow-lg">
      <CardBody>
        <Typography
          variant="h5"
          color="blue-gray"
          className="mb-4 flex items-center justify-between"
        >
          Last Records
          <Link to="/records" onClick={scrollToTop}>
            <Button size="sm" variant="text" className="flex gap-2">
              View All
              <ArrowLongRightIcon strokeWidth={2} className="w-4 h-4" />
            </Button>
          </Link>
        </Typography>
      </CardBody>
    </Card>
  );
}

So the problem I have is that when I go back to the page I came from (by clicking the ‘Back’ button), that page should load/focus on the place where the link that took me to that other page was clicked (the one where there is a ‘Back’) button. That is now not the case because obviously I don’t know how to implement that…

Lets see full example (I will exclude imports because of the boilerplate):

HomePage – we are on the Home page:

function HomePage() {
  return (
    <>
      <div className="overflow-hidden">
        <Menu />

        <div className="h-6 bg-green-50"></div>

        <div className="flex justify-center min-h-screen bg-green-50">
          <div className="mt-2">
            <div className="mx-6">
              <TrendCard />
            </div>

            <div className="mt-8 mx-6">
              <LastRecordsCard />
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

LastRecordsCard (where the link to the next page is) – on the Home Page, we scroll down to this component and we want to click on the View All link:

export default function LastRecordsCard() {
  function scrollToTop() {
    window.scrollTo(0, 0);
  }

  return (
    <Card className="w-full shadow-lg">
      <CardBody>
        <Typography
          variant="h5"
          color="blue-gray"
          className="mb-4 flex items-center justify-between"
        >
          Last Records
          <Link to="/records" onClick={scrollToTop}>
            <Button size="sm" variant="text" className="flex gap-2">
              View All
              <ArrowLongRightIcon strokeWidth={2} className="w-4 h-4" />
            </Button>
          </Link>
        </Typography>

Page that renders on the /records path (RecordsPage) – new page is loaded:

function RecordsPage() {
  return (
    <>
      <div className="overflow-hidden">
        <Menu />

        <div className="h-6 bg-green-50"></div>

        <div>
          <PageHeader title="Records" />
        </div>

        <div className="flex justify-center min-h-screen bg-green-50">
          <div className="mt-2">
            <div className="mx-6">
              <RecordsList />
            </div>

            <div>
              <PageWidthLayout />
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

export default RecordsPage;

And finally PageHeader component that is common for almost all headers – we see ‘Back’ button and we want to go back to the previous page on the place where we clicked the ‘View All’ link:

const PageHeader = ({ title }) => {
  const navigate = useNavigate();

  const handleGoBack = () => {
    // Redirects the user back to the previous page they came from
    navigate(-1);
  };

  return (
    <div className="h-24 flex flex-col">
      <div>
        <Button variant="text" className="flex gap-2" onClick={handleGoBack}>
          <ArrowLeftIcon strokeWidth={2} className="w-4 h-4" />
          Back
        </Button>
      </div>

      <div>
        <Typography variant="h3" color="black" className="mb-2 mx-4">
          {title}
        </Typography>
      </div>
      <hr
        className="my-2 border-green-100"
        style={{ boxShadow: "0px 2px 4px rgba(0, 0, 0, 0.2)" }}
      />
    </div>
  );
};

export default PageHeader;

Any idea how to solve this? I’ve been stuck on this functionality for days, but no matter what I do, I can’t move from the dead spot.

2

Answers


  1. Chosen as BEST ANSWER

    So i found that scrollToTop() function was responsible for the strange behavior. I followed Muhammad Idrees answer and found that I can't store the scrollY because of the scrollToTop function which automatically stored the scrollY with a value of 0.

    I deleted that function and did the following:

    In the LastRecordCard component I added function from the Muhammad Idrees answer:

    function storeScrollPosition() {
            const scrollY = window.scrollY;
            sessionStorage.setItem('scrollPosition', scrollY);
        }
    

    But in the same component, I used only that function in the link:

    <Link to="/records" onClick={() => { storeScrollPosition(); }}>
    

    In the PageHeader component I wrote this:

    useEffect(() => {
            const scrollPosition = sessionStorage.getItem('scrollPosition');
            if (scrollPosition) {
                window.scrollTo(0, parseInt(scrollPosition));
                sessionStorage.removeItem('scrollPosition');
            } else {
                window.scrollTo(0, 0);
            }
        }, []);
    

    In this way, I kept the behavior that the new page automatically scrolls to the top, but if we want to go back, the previous page will be loaded from where we left it.


  2. to implement a behaviour where, when a user clicks the "Back" button and returns to the previous page, the page should scroll to the same position where the user clicked the "View All" link.

    When the user clicks the "View All" link, you need to store the current scroll position in the browser’s storage

    export default function LastRecordsCard() {
        function scrollToTop() {
            window.scrollTo(0, 0);
        }
    
        function storeScrollPosition() {
            sessionStorage.setItem('scrollPosition', window.scrollY);
        }
    
        return (
            <Card className="w-full shadow-lg">
                <CardBody>
                    <Typography variant="h5" color="blue-gray" className="mb-4 flex items-center justify-between">
                        Last Records
                        <Link to="/records" onClick={() => { scrollToTop(); storeScrollPosition(); }}>
                            {/* ... */}
                        </Link>
                    </Typography>
                </CardBody>
            </Card>
        );
    }
    

    In the PageHeader component, you can use the stored scroll position to restore the previous position when the user navigates back.

    import React, { useEffect } from 'react';
    import { Button, Typography } from "@material-tailwind/react";
    import { ArrowLeftIcon } from "@heroicons/react/20/solid";
    import { useNavigate } from 'react-router-dom';
    
    const PageHeader = ({ title }) => {
        const navigate = useNavigate();
    
        const handleGoBack = () => {
            navigate(-1);
        };
    
        useEffect(() => {
            const scrollPosition = sessionStorage.getItem('scrollPosition');
            if (scrollPosition) {
                window.scrollTo(0, parseInt(scrollPosition));
                sessionStorage.removeItem('scrollPosition');
            }
        }, []);
    
        return (
            // ...
        );
    };
    
    export default PageHeader;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search