I have this Feed component. The idea is to preserve scroll on multiple feeds (tabs), e.g. I’m on localhost/feed-one
, I scroll to 500px, switch to localhost/feed-two
, and when I return to feed 1, the scroll should be back on 500px. The following code works as expected, yet ESLint shows an error, and I want to fix it.
import React, { useState, useEffect } from 'react';
import { useParams, useLocation } from 'react-router-dom';
import Loader from '../Loader/Loader';
import Post from '../Post/Post';
import Data, { Post as PostType } from '../../emulateAPI/Data';
import useScrollRestoration from '../../hooks/useScrollRestoration';
import './Feed.scss';
interface FeedProps {
data: Data;
}
const Feed: React.FC<FeedProps> = (props) => {
const { data } = props;
const { categorySlug } = useParams<string>();
const [isLoading, setIsLoading] = useState<boolean>();
const [posts, setPosts] = useState<PostType[]>([]);
const location = useLocation();
const reScroll = useScrollRestoration();
useEffect(() => {
setIsLoading(true);
const category = data.getCategoryBySlug(categorySlug);
if (category) {
setPosts(data.getPostsByCategory(category));
}
setIsLoading(false);
}, [categorySlug, data]);
useEffect(() => {
reScroll();
}, [posts]); //I GET THE ERROR HERE: React Hook useEffect has a missing dependency: 'reScroll'.
return (
<>
{isLoading ? (
<Loader />
) : (
<div className='feed'>
{posts.map((post, index) => (
<Post key={index} post={post} />
))}
</div>
)}
</>
);
}
export default Feed;
My custom hook useScrollRestoration:
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
const useScrollRestoration = () => {
const location = useLocation();
useEffect(() => {
const onScroll = () => {
sessionStorage.setItem(location.pathname, window.scrollY.toString());
};
window.addEventListener('scroll', onScroll);
return () => {
window.removeEventListener('scroll', onScroll);
};
}, [location.pathname]);
return (() => {
const scrollY = sessionStorage.getItem(location.pathname);
window.scrollTo(0, +(scrollY || 0));
});
};
export default useScrollRestoration;
The error is in the Feed component: "React Hook useEffect has a missing dependency: 'reScroll'. Either include it or remove the dependency array."
But if I do add reScroll in the useEffect’s dependency array, the useEffect gets called on location.pathname
changes when new posts haven’t been loaded yet and the scroll is often impossible (e.g. I can’t scroll back to 500px because the posts haven’t loaded yet, React scrolls to say 250px, posts finally load, but the value is already overwritten to 250px). Can I fix this? Any help is much appreciated!!!
2
Answers
Here's what I've come up with using refs. I only want to call
reScroll()
when user has already switched feeds and all the relevant posts have been loaded, not just whenlocation.pathname
changes. So there's a need to indicate that the posts have been loaded, and setting state won't help because it won't take immediate effect. Working solution for my use case:I'm a noob, so let me know what you think.
You can only call the
rescroll
when you have posts loaded like: