When the button is clicked, my list is replaced with a one-item list. When I click on the "return to list" button, I want to return to the same list and to the same place in the list to which I scrolled.
useEffect(() => {
if (props.specialOfferRestaurant) {
localStorage.setItem('scrollPosition', String(window.scrollY))
localStorage.setItem('restaurants', JSON.stringify(allRestaurants));
window.scrollTo(0, 0)
setAllRestaurants([props.specialOfferRestaurant])
} else if (!props.specialOfferRestaurant && localStorage.length > 0) {
setAllRestaurants(JSON.parse(localStorage.getItem('restaurants')))
window.scrollTo(0, Number(localStorage.getItem('scrollPosition')))
localStorage.clear();
}
}, [props.specialOfferRestaurant])
In this code, everything works except for the line that returns the scroll to the right place. The same line that returns the scroll to 0 also works.
The scroll position is stored in localStorage without problems. If I add this to the bottom of the code:
console.log(Number(localStorage.getItem('scrollPosition')))
I see that the correct scroll Y value is stored in localStorage
I can't figure out what's wrong.
CodePudding user response:
To fix this issue, you can use the window.pageYOffset
property instead of the window.scrollY
property to get the scroll position of the page. The window.pageYOffset
property is updated whenever the page is scrolled, either manually or programmatically.
updated answer as new description To fix this issue, you can use a separate useEffect hook to update the list, and ensure that it is executed after the scroll position has been set. This will ensure that the list is updated before the page is scrolled, and the scroll position is correct.
useEffect(() => {
if (props.specialOfferRestaurant) {
localStorage.setItem("scrollPosition", String(window.scrollY));
localStorage.setItem("restaurants",
JSON.stringify(allRestaurants));
window.scrollTo(0, 0);
setAllRestaurants([props.specialOfferRestaurant]);
} else if (!props.specialOfferRestaurant && localStorage.length > 0) {
setAllRestaurants(JSON.parse(localStorage.getItem("restaurants")));
window.scrollTo(0, Number(localStorage.getItem("scrollPosition")));
localStorage.clear();
}
}, [props.specialOfferRestaurant]);
useEffect(() => {
if (props.specialOfferRestaurant && localStorage.length > 0) {
setAllRestaurants(JSON.parse(localStorage.getItem("restaurants")));
}
}, [props.specialOfferRestaurant]);
CodePudding user response:
The correct answer was found thanks to @Md. Mohaiminul Hasan and it comes from the assumption that the list from localStorage does not have time to render and therefore the scroll cannot be applied to the middle of the list. The final, working code looks like this:
useEffect(() => {
if (!props.specialOfferRestaurant && localStorage.length > 0) {
window.scrollTo(0, Number(localStorage.getItem('scrollPosition')))
localStorage.clear();
}
}, [allRestaurants]);
useEffect(() => {
if (props.specialOfferRestaurant) {
localStorage.setItem('scrollPosition', String(window.scrollY))
localStorage.setItem('restaurants', JSON.stringify(allRestaurants));
window.scrollTo(0, 0)
setAllRestaurants([props.specialOfferRestaurant])
} else if (!props.specialOfferRestaurant && localStorage.length > 0) {
setAllRestaurants(JSON.parse(localStorage.getItem('restaurants')))
}
}, [props.specialOfferRestaurant])