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
The issues is that if you select same item after you scroll up, you'd 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>
);
}