React

컴포넌트 랜더링과 자바스크립트의 속도 차이(무한스크롤 part2)

변기원 2022. 5. 11. 00:32

 

인스타 클론을 할 때는 전체 document에서 무한스크롤을 구현했다면 이번 실전 프로젝트에는?

오른쪽 사진에 보이는 빨간색 테두리의 div만 무한스크롤을 적용하고 싶습니다!

인스타 클론 때 작업했던(강의에서 들었던 scroll파일 그대로) 파일입니다. 특히나 위에 부분이 이해가 잘 안 갔는데, 이번에 저부분을 건들지 않고는 무한스크롤을 구현할 수 없는 상황이 되었습니다.

저는 지금 모바일 화면으로 구현을 하고 있으며,

저 코드를 그대로 적용하면 scrollHeight - innerHeight - scrollTop < 100 이 되는 순간은 영원히 없을 것입니다.

 

그렇다면 어떻게 마지막 스크롤 지점을 찾을 것인가!

일단 막막하니까 dom을 가져와서 스크롤 이벤트를 찍어봅시다. 보면 뭔가 있겠지요..?

역시 뭔가 있습니다. 하나하나 열어보면 뭔가 스크롤 위치를 나타내는 것 같다? 싶은 게 있습니다! 

그걸 하나하나 콘솔에 찍어보면서 저는 저렇게 세 가지 값을 찾았습니다.

이렇게 적절한 위치에서 callNext() 함수가 실행되도록 할 수 있었습니다! ㅎㅎ

이것은 콘솔에 숫자를 찍어보면서 찾는 게 답인 것 같습니다. 

 

 

22.5.13 추가

리액트 컴포넌트에서 getElementById를 써서 돔요소를 가져왔더니 새로고침 했을 때 무한스크롤이 기능하지 않는 에러가 있었습니다.

그 이유는 컴포넌트 랜더링보다 자바스크립트가 빨라서 처음에 새로고침 했을때 getElementById에 입력된 id값의 태그가 없는 것이었습니다.

https://stackoverflow.com/questions/68768026/react-getelementbyid-is-null

 

react getElementById is null

import React, { useEffect, useState } from 'react' const Download = () => { const desc = document.getElementById('description') useEffect(() => { desc.innerHTML = '<h1>...

stackoverflow.com

미처 랜더링되기도 전에 선택하려 하니 당연히 null 이 되어서 새로고침 했을 때는 위에서 정의한 container가 없는 상황입니다.

다른 컴포넌트를 돌아다니다가 다시 작동해보면 그때는 잘 됩니다. 이미 랜더링이 완료된 상태니까요..

https://stackoverflow.com/questions/57842598/react-functional-component-immediately-calling-getelementbyid-returns-null

 

React Functional Component: Immediately calling getElementById returns null

If I add a timeout with 0ms then I can console log the elements that I have selected with document.getElementById but if I remove the 0 ms timeout they all return null. What's going on here? import

stackoverflow.com

일단 리액트에서 getElementById를 사용하는 걸 추천하지는 않는 것 같습니다.

보통 useRef를 사용하라고 하는데 저는 부모 컴포넌트가 자식 컴포넌트로 ref를 보내줘야 하는 상황이라서 useRef를 사용할 수 없었습니다. 구글링을 통해 ref를 props처럼 전달하는 방법을 찾았고 바로 forwardRef입니다.

forwardRef를 사용하면 ref를 마치 Props처럼 자식에게 전달할 수 있습니다.

하지만 forwardRef를 써도 null이 undefined로만 바뀌었을 뿐, 여전히 랜더링보다 자바스크립트가 빨라서 쓸 수 없었습니다.

그래서 아래와 같이 callNext함수가 불려질 때 부모 컴포넌트가 보내준 ref를 다시 찾았습니다.

이를 통해 언제나 제대로 동작하는 무한스크롤을 구현했습니다.