오늘은 사이드 프로젝트 구현 중, useRef를 활용하여 동적으로 움직이는 랜딩 페이지를 구현한 경험을 공유하려고 한다.
useRef에 대해서는 이전에 작성한 게시글을 참고하면 좋을 것 같다.
2024.04.29 - [🎬Project] - [React] useRef 훅에 대해 이해하기 ( + useState와 let과의 차이점 )
[React] useRef 훅에 대해 이해하기 ( + useState와 let과의 차이점 )
리액트를 사용해 개발을 하다 보면, 'useState' 나 'useEffect' 같은 훅을 많이 사용하게 된다.하지만 저 둘에 비해 'useRef' 훅은 자주 사용하지 않았었는데이번에 동적인 랜딩 페이지를 구현하면서 사
soondububu.tistory.com
📕 1. 랜딩 페이지를 구현하려 했던 이유
타 사이트를 이용하다 보면,
1. 어떤 버튼을 눌렀을 때 화면의 특정 영역으로 슬라이드가 이동되거나
2. 특정 영역에 도달했을 때, 그제서야 사진들이 나온다거나 하는 기능들이 존재한다.
내 경험담이지만, 나는 위의 기능들이 들어가있는 랜딩페이지를 보면
그 회사에 대한 호기심이 더 생겨서 페이지에 있는 이것저것들을 눌러보게 된다.
그래서인지 나도 '랜딩 페이지'라는 것을 제대로 만들어 보고 싶었고,
사이드 프로젝트에 해당 기능을 적용해봐야겠다는 생각이 들었다.
📕 2. 랜딩 페이지 구현 과정
( 아직 초안이라 많이 부족한 것을 감안하고 봐주세요. )
내가 구현한 랜딩 페이지는 총 5개의 섹션으로 이루어져 있다.
어떤 사이트인지를 간단하게 나타내는 1개의 메인 화면과
사이트 내에 존재하는 기능 4개 각각을 간략하게 설명한 4개의 화면으로 구성되어 있다.
먼저, 랜딩 페이지가 렌더링 되면 가장 먼저 보이는 영역은 다음과 같다.
사진 하단에 있는 더블 화살표 버튼이 통통 튀고 있는데
저 버튼을 누르면 바로 아래에 있는 2번째 화면으로 이동하도록 구현했다.
이 기능을 구현한 방식을 설명해보면 다음과 같다.
내 메인 화면의 코드를 살펴 보면,
각각의 화면 영역을 컴포넌트로 분리한 뒤에 불러온 후,
최상단 컴포넌트에서 2번째 화면 영역의 ref인 'secondSectionRef'를 만든 뒤에
첫 번째 화면과 두 번째 화면에 각각 props로 ref를 넘겨주었다.
Roulette.tsx
두 번째 화면에서는 ref를 받아서
두 번째 화면의 div에 ref를 연결해 주어 이 DOM 요소에 직접 접근할 수 있도록 해주었다.
Introduce.tsx
첫 번째 화면에서는 화살표 버튼에 아래와 같이 onClick을 걸어놓은 뒤,
해당 화살표 버튼을 누르면
Roullet.tsx에서 연결해 둔 secondSectionRef로 이동하게 설정해 두었다.
📕 사진과 글에 애니메이션 적용하기
화살표 버튼을 눌러 이동하는 것 말고
해당 화면이 보이기 시작하면 그때부터 사진과 글이 나타나게 되는 기능을 추가로 구현했다.
이 기능을 구현한 방식은 다음과 같다.
FoodMap.tsx
먼저 각 컴포넌트마다 useRef를 사용해 ref를 생성해 준 후 해당 컴포넌트에 바로 연결해 주었다.
이후 아래에 있는 useScrollVisible이라는 커스텀 훅에 ref 객체를 던져주었다.
커스텀 훅에서는 현재 해당 컴포넌트를 보고 있는지 아닌지 확인하여 해당 컴포넌트를 보고 있으면 true를 반환해 주었다.
반환된 값이 true이면 애니메이션을 적용할 수 있도록 구현했다.
위의 사진에 있는 animate-scroll-fade-in 은
tailwind css에 있는 유틸리티 클래스가 아닌, tailwind.config.ts에
내가 직접 커스텀해둔 애니메이션이니 궁금한 분은 아래 코드에서 확인하면 좋을 것 같다.
useScrollVisible.tsx
따로 만들어둔 커스텀 훅에서 현재 섹션을 보고 있는지 아닌지를 판별해서
Boolean 값을 리턴하게 해 두었다.
📕 트러블 슈팅 기록
만들어 놓은 useScrollVisible 훅에서
사용자가 현재 해당 화면 영역을 보고 있는지 아닌지만 판별했더니 한 가지 문제점이 발생했다.
맨 아래까지 스크롤을 내린 후에 다시 위로 올리면,
이미 보면서 내려온 화면임에도 또다시 새로 사진과 글에 대해 애니메이션이 적용되는 현상이 발생한 것이다.
사용자 입장에서 생각해 봤을 때, 이미 끝까지 스크롤을 내렸다면
다시 위로 스크롤을 올리더라도 사진과 글이 다 나타나있어야 한다고 생각했다.
매번 스크롤을 올리고 내릴 때마다 계속 사진과 글에 대해 애니메이션 효과가 나타나면
사용자 경험 측면에서도 좋지 않을 것이라 생각했기 때문에,
hasBeenVisible 이란 변수를 만들어 애니메이션이 한 번 사용자에게 보였다면
그 이후로는 다시 애니메이션 효과가 나타나지 않도록 설정해 두었다.
📕 느낀 점
앱이든 웹이든 랜딩 페이지를 만들어 본 경험은 있지만,
useRef와 애니메이션을 활용하여 구현한 경험은 처음이라 재밌었다.
지금까지 만든 것은 초안이라 아직 많이 미흡하지만,
그만큼 개선해야 할 점을 찾을 수 있으니 이런저런 디테일을 추가하면서 흥미를 느낄 수 있어서 좋은 것 같다.
'🎬Project' 카테고리의 다른 글
[CSS] Tailwind CSS에서 반응형 디자인 적용하기 (1) | 2024.07.01 |
---|---|
[Project] Vercel 배포시에 이미지 렌더링 속도 저하 문제를 해결한 경험 (5) | 2024.06.24 |
[React] useRef 훅에 대해 이해하기 ( + useState와 let과의 차이점 ) (0) | 2024.04.29 |
[Next.js] 외부 API KEY값 노출 문제 해결하기 (0) | 2024.04.18 |
[Next.js] AWS S3와 next/image를 사용해 이미지 최적화를 진행한 경험 (0) | 2024.04.13 |