Question:
Fix ScrollIntoView not working issue

Problem:

The Problem :- The scrollIntoView is working fine but, it fails for this scenario when suppose I click on John Doe it scrolls to that section but now when I scroll to top and select again John Doe then it does not get scrolled to that particular section Why is this happening ? Note :- This happens for all the buttons not just for John Doe

In the useEffect Dependency array I have added the selectedAdvisor state variable so that whenever it changes then it should scrollIntoView of that section based on the id

Expected Output :- scrollIntoView should work properly even if I scroll to top and then select the element that was already selected example John Doe


Below is my code :

import React, { useEffect, useState } from "react";


function AdvisorCard() {

  return <div className="advisorCard"></div>;

}

export const NewFilterAdvisor = () => {

  const [selectedAdvisor, setSelectedAdvisor] = useState("Tony Stark");


  useEffect(() => {

    let ele = document.getElementById(`${selectedAdvisor}`);

    if (ele) {

      ele.scrollIntoView({

        behavior: "smooth",

        block: "center",

      });

    }

  }, [selectedAdvisor]);


  return (

    <div className="newFilterAdvisorContainer">

      <div className="advisorsBtnContainer">

        <button

          onClick={() => setSelectedAdvisor("Tony Stark")}

          className="advisorBtn"

        >

          Tony Stark

        </button>

        <button

          onClick={() => setSelectedAdvisor("Steve Rogers")}

          className="advisorBtn"

        >

          Steve Rogers

        </button>

        <button

          onClick={() => setSelectedAdvisor("Bruce Banner")}

          className="advisorBtn"

        >

          Bruce Banner

        </button>

        <button

          onClick={() => setSelectedAdvisor("Thor")}

          className="advisorBtn"

        >

          Thor

        </button>

        <button

          onClick={() => setSelectedAdvisor("John Doe")}

          className="advisorBtn"

        >

          John Doe

        </button>

      </div>


      <div id="Tony Stark" className="advisorSection">

        <h1 className="advisorCardContainerHeading">Tony's Advisors</h1>

        <div className="advisorCardContainer">

          <AdvisorCard />

          <AdvisorCard />

          <AdvisorCard />

        </div>

      </div>


      <div id="Steve Rogers" className="advisorSection">

        <h1 className="advisorCardContainerHeading">Steve's Advisors</h1>

        <div className="advisorCardContainer">

          <AdvisorCard />

          <AdvisorCard />

          <AdvisorCard />

        </div>

      </div>


      <div id="Bruce Banner" className="advisorSection">

        <h1 className="advisorCardContainerHeading">Bruce's Advisors</h1>

        <div className="advisorCardContainer">

          <AdvisorCard />

          <AdvisorCard />

          <AdvisorCard />

        </div>

      </div>


      <div id="Thor" className="advisorSection">

        <h1 className="advisorCardContainerHeading">Thor's Advisors</h1>

        <div className="advisorCardContainer">

          <AdvisorCard />

          <AdvisorCard />

          <AdvisorCard />

        </div>

      </div>


      <div id="John Doe" className="advisorSection">

        <h1 className="advisorCardContainerHeading">John's Advisors</h1>

        <div className="advisorCardContainer">

          <AdvisorCard />

          <AdvisorCard />

          <AdvisorCard />

        </div>

      </div>

    </div>

  );

};


CodeSandBoxLink :- >https://codesandbox.io/s/keen-darkness-g42qjw?file=/src/App.js:1443-1470


Where am I going wrong ? please help


Solution:

The issue is that if you select same item after scrolling up, you'll update the state to the same value and the useEffect won't run. Actually, you don't even need an internal state. This would do just fine:

import React from "react";

import "./styles.css";

function AdvisorCard() {

  return <div className="advisorCard"></div>;

}

export default function App() {

  const handleSelectItem = (id) => {

    let ele = document.getElementById(`${id}`);

    if (ele) {

      ele.scrollIntoView({

        behavior: "smooth",

        block: "center"

      });

    }

  };


  return (

    <div className="newFilterAdvisorContainer">

      <div className="advisorsBtnContainer">

        <button

          onClick={() => handleSelectItem("Tony Stark")}

          className="advisorBtn"

        >

          Tony Stark

        </button>

        <button

          onClick={() => handleSelectItem("Steve Rogers")}

          className="advisorBtn"

        >

          Steve Rogers

        </button>

        <button

          onClick={() => handleSelectItem("Bruce Banner")}

          className="advisorBtn"

        >

          Bruce Banner

        </button>

        <button

          onClick={() => handleSelectItem("Thor")}

          className="advisorBtn"

        >

          Thor

        </button>

        <button

          onClick={() => handleSelectItem("John Doe")}

          className="advisorBtn"

        >

          John Doe

        </button>

      </div>


      <div id="Tony Stark" className="advisorSection">

        <h1 className="advisorCardContainerHeading">Tony's Advisors</h1>

        <div className="advisorCardContainer">

          <AdvisorCard />

          <AdvisorCard />

          <AdvisorCard />

        </div>

      </div>


      <div id="Steve Rogers" className="advisorSection">

        <h1 className="advisorCardContainerHeading">Steve's Advisors</h1>

        <div className="advisorCardContainer">

          <AdvisorCard />

          <AdvisorCard />

          <AdvisorCard />

        </div>

      </div>


      <div id="Bruce Banner" className="advisorSection">

        <h1 className="advisorCardContainerHeading">Bruce's Advisors</h1>

        <div className="advisorCardContainer">

          <AdvisorCard />

          <AdvisorCard />

          <AdvisorCard />

        </div>

      </div>


      <div id="Thor" className="advisorSection">

        <h1 className="advisorCardContainerHeading">Thor's Advisors</h1>

        <div className="advisorCardContainer">

          <AdvisorCard />

          <AdvisorCard />

          <AdvisorCard />

        </div>

      </div>


      <div id="John Doe" className="advisorSection">

        <h1 className="advisorCardContainerHeading">John's Advisors</h1>

        <div className="advisorCardContainer">

          <AdvisorCard />

          <AdvisorCard />

          <AdvisorCard />

        </div>

      </div>

    </div>

  );

}


Suggested blogs:

>How you can create array with associative array in other array php?

>How you can send email from a shared inbox in Python

>How you can Show or hide elements in React?

>Instance deployment failed to install Composer dependencies

>Integrate SASS into the build and consume a UI toolkit

>Invoking Python script from scons and pass ARGLIST

>Migrate From Haruko To AWS App: 5 Simple Steps


Ritu Singh

Ritu Singh

Submit
0 Answers