인프런 커뮤니티 질문&답변

Jin님의 프로필 이미지
Jin

작성한 질문수

[리뉴얼] React로 NodeBird SNS 만들기

window.addEventListener("scroll", onScroll)관련 질문이 있습니다.

작성

·

611

0

안녕하세요, 현재 redux saga를 사용하지 않고 노드버드를 다시 만들고 있습니다. 그런데 스크롤을 내리면 자동으로 포스트 들을 가져오는 부분에서 문제가 발생해서 질문 남깁니다.

원래 강의에서는 

function onScroll() {
    if (
      window.scrollY + document.documentElement.clientHeight >
      document.documentElement.scrollHeight - 300
    ) {
      if (hasMorePosts && !loadPostLoading) {
        const lastId = mainPosts[mainPosts.length - 1]?.id;
        dispatch(postActions.loadPostRequest(lastId));
      }
    }
  }

  useEffect(() => {
    dispatch(postActions.loadPostRequest());
  }, []);

  useEffect(() => {
    window.addEventListener("scroll"onScroll);
    return () => {
      window.removeEventListener("scroll"onScroll);
    };
  }, []);

이런식으로 코드를 짰고 saga의 throtle과 loadPostLoading을 이용해서 스크롤이 끝부분에 도달핼 때 중복으로 여러번 포스트를 가져오는 것을 방지했습니다. 지금은 saga를 안 쓰고 있기 때문에 아래처럼 코드를 짰습니다.

const [tweetssetTweets= useState([]);
  const [hasMorePostssetHasMorePosts= useState(false);
  const [loadTweetLoadingsetLoadTweetLoading= useState(false);

  async function getTweets() {
    try {
      setLoadTweetLoading(true);
      const newTweets = await tweetFunctions.getTweets();
     setHasMorePosts(newTweets.length === 10);      
      setTweets(tweets);
    } catch (error) {
      console.error(error);
    } finally {
      setLoadTweetLoading(false);
    }
  }

  // 스크롤이 최하단에 가까워지면 트윗들을 추가로 가져옴
  async function onScroll() {
   if (
      window.scrollY + document.documentElement.clientHeight >
      document.documentElement.scrollHeight - 300
   ) {   
      if (hasMorePosts && !loadTweetLoading) {      
        console.log("````loadTweetLoading", loadTweetLoading);
        console.log("````tweets"tweets);
        const newTweets = await tweetFunctions.getTweets(lastId);
        setTweets(prev => [...prev, ...newTweets]);
      }
    }
  }
  useEffect(() => {
    getTweets();
 }, []);

  useEffect(() => {
    window.addEventListener("scroll"onScroll);
    return () => {
      window.removeEventListener("scroll"onScroll);
    };
  }, []);

문제는 onScroll() 함수가 실행 될 때 외부에 있는 tweets, loadTweetLoading과 같은 변수들의 값이 변해도 전혀 반영을 하지 않고 처음 세팅된 tweets( [] )와 loadTweetLoading(false)의 값을 유지하고 있습니다. 그래서 스크롤이 아래로 내려가면   await tweetFunctions.getTweets  함수가 여러번 호출됩니다.

저는 onScroll() 함수 내부에서 외부의 변수들을 인지하지 못하는 이유와 해결방법이 궁급합니다. 

그리고 혹시 axios를 이용해서 saga의 throtle과 비슷한 기능을 할수 있나요?

답변 2

0

Jin님의 프로필 이미지
Jin
질문자

이벤트 추가라 그걸 생각 못했네요. 감사합니다.

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

  useEffect(() => {
    window.addEventListener("scroll"onScroll);
    return () => {
      window.removeEventListener("scroll"onScroll);
    };
 }, []);

[]에 loadTweetLoading이나 tweets같은 디펜던시들을 넣어주세요.

Jin님의 프로필 이미지
Jin

작성한 질문수

질문하기