Lynx의 튜토리얼은 Product Gallery 만들기와 Product Detail 만들기로 구성되어 있다. 나는 그 중에서 갤러리 만들기를 먼저 해볼 예정이다.
지난 Quick Start에 이어서 공식문서 탐방을 하고 있다.
Tutorial: Product Gallery를 보며 기록했다. 주로 복붙했다. 작업하면서 뭔가 이상하다고 느낀 부분의 코드만 살짝살짝 바꿔서 했다.
블로그 글로 업로드하는 내용은 분량상 2편으로 나눠서 진행한다. 이 글은 지난 글에 이어서 쓰는 Part 2다.
- Part 1 : 프로젝트 세팅부터 global style, component 하나 만들기, useState 사용하기
- Part 2 : list 태그 사용하기, Auto-Scrolling, MTS(Main Thread Script)로 메인 스레드 다루기
list 태그로 이미지 줄 세우기
list
태그에는 list-item
이라는 자식 태그가 필요하다. 이 점을 유의하며 작업해야한다.
먼저 src/utils.tsx
를 복붙했다.
튜토리얼에서 코드가 없어서 당황했는데, 튜토리얼 내에서도 utils 코드는 저 아래에 숨겨져 있다.
그리고 타입이 뭔가 잘못된 것처럼 보인다.
utils의 코드에 타입 정의가 잘못된 것처럼 보이는데, 일단 진행했다.
이제 src/Gallery.tsx
를 만든다. 코드 내용을 정리해보자.list
태그 내에 list-item
태그를 사용한 모습을 볼 수 있다. utils
의 calculateEstimatedSize
함수를 끌어다가 사용했다.
그리고 list-item
태그에는 item-key
와 key
가 따로 있는데, 이유는 모른다.
list-item에는 item-key가 필요하고, map 함수로 순회해서 컴포넌트를 만들기 때문에 key를 쓰는걸로 보이긴 한다.
✅ 공식문서 - Lynx list 태그 ➡️ 나중에 읽어봐야겠다.
App.tsx
에는 기존에 ImageCard
컴포넌트를 사용하던 코드를 지우고 Gallery
컴포넌트만 넣는다.
짠. 두 줄로 가구 사진이 보인다. 사진별로 좋아요 버튼도 누를 수 있다.
Auto-Scrolling
리스트를 스크롤로 쭉 내리면 사진이 줄줄이 두 줄로 나오는데, 오토 스크롤을 적용해서 자동으로 조금씩 내려가게 만들 수 있다.
이때 사용하는 키워드(?)는 invoke
이다.
일단 import
에서 지난 useState
와 마찬가지로 useEffect
, useRef
를 React
가 아닌 @lynx-js/react
에서 가져온다. Ref 타입도 미리 정의되어 있는 모습을 볼 수 있다.
코드는 list 태그를 참조하고, autoScroll 메소드를 실행하겠다라고 이해하면 된다.
✅ invoke
- Lynx에서 (list 같은) 네이티브 엘리먼트에는 참조를 통해 호출할 수 있는 메소드가 존재한다.
- 웹이랑 달리 이런 메소드 호출은 메시지 전달과 유사한 비동기식으로 이뤄진다고 한다.
- 메소드(method)와 매개변수(params)를 포함하여 invoke를 실행했을 때 동작한다고 한다.
- 사실 잘 모르겠다. 이건 공식문서 어디에서 찾아야할까
아무튼 auto scrolling 완성
Custom Scrollbar
스크롤바를 이쁘게 만들어보자.
NiceScrollbar.tsx
컴포넌트를 만든다.
forwardRef는 React 19버전부터는 필요없어졌지만 아직 Lynx에서는 쓰고 있다.
React 코드라서 딱히 설명할건 없지만 이런 코드를 갖고 있다.
useState
로 스크롤바의 높이와 스크롤 위치를 0으로 맞추고 시작한다.- 현재 디바이스의 높이와 dpi를 통해 리스트의 높이를 계산하고 전체 컨텐츠의 영역 비율에 따라 스크롤바 높이, top 위치 계산.
- 계산된 스크롤바 높이와 top 위치 state 업데이트.
useImperativeHandle
훅으로ref.current.adjustScrollbar( ~~~ )
로 외부에서 이 함수를 호출할 수 있게 한다.
스크롤바 컴포넌트를 ref와 함께 말아서 꽂아넣는다.
짠. 스크롤바가 생겼다.
Main Thread Script로 더 생동감있는 스크롤바 만들기
앞서 정리했던 공부 내용인 Why Lynx에서 나오는 것처럼 Lynx는 스레드 2개로 이뤄져있다. 그 중에서 main thread를 사용해서 스크롤바 연산을 더 빠르게 하는 방식을 해보자.
다시 2개의 스레드를 소개하자면 아래와 같다.
- 메인 스레드는 상태 업데이트, 이벤트 처리, 비즈니스 로직 등에 사용
- 렌더링 스레드는 레이아웃 계산, UI 트리 구성, 실제 화면 렌더링 등에 사용
NiceScrollbarMTS.tsx
를 만들어보자.
코드는 크게 두 가지로 나눌 수 있다. 하나는 함수, 하나는 컴포넌트다.
adjustScrollbarMTS
함수를 보자."main thread";
키워드(?)를 넣게 되면 메인 스레드에서 동작하라는 의미로 쓰인다.
next.js에서 "use server"를 사용한 서버 액션와 비슷한 느낌으로 작성한다.
ref로 연결된 UI 요소(NicScrollbarMTS)의 style에 직접 접근해서 속성을 바꿀 수 있게 한다.
NiceScrollbarMTS
컴포넌트를 보자.
또 특이한 코드는 main-thread:ref
. Lynx 전용 속성이며 메인 스레드에서 직접 조작할 수 있도록 ref 연결한다는 의미라고 한다. 이 ref는 위 adjustScrollbarMTS
에서 사용된다.
Gallery.tsx
에 기존 스크롤을 제거하고 MTS 컴포넌트를 넣어보자.
먼저 useMainThreadRef라는 훅을 사용하고 "main thread"; 키워드로 메인스레드에서 동작하라는 의미를 넣어준다. 앞서만든 onScollbarMTS 함수를 사용했다.
컴포넌트를 넣고 list 태그에도 bindscroll로 이벤트 핸들링을 넣어준다.
튜토리얼에서 예시로 그냥 스크롤과 MTS 스크롤을 동시에 띄워서 보여주니까 그걸 보면 된다. 반응이 빠릿한게 MTS다.
(추가 공부) 기본 방식과 MTS 방식 Scrollbar 차이
기본 방식은 useState를 사용한다. 스크롤을 옮기면 상태가 변경되면 리렌더링을 하게 된다.
MTS 방식은 스크롤을 옮기면 ref를 사용해 바로 DOM 조작을 하기에 더 빠르게 조작할 수 있다.
그렇지만 코드를 읽어봐도 기본 방식은 기존에 잘 아는 React 문법이지만 MTS 방식은 뭔가 복잡하다.
추상화가 잘 안된 느낌이라고 해야할까? 직관적이지 않다. 성능을 위해서 이런걸 감수해야하나 싶어지는 뭔가 짜치는 문법들이 보인다.
마치며
모르는게 너무 많다. 스레드 개념에 대해서 더 알면 도움이 되겠다는 생각이 든다.
그리고 MTS 방식을 써보니 코드가 좀 짜치는 느낌이 든다. 쌈뽕하게 딱 떨어지지 않는게 미래에는 개선이 될 것 같다.
이 오픈소스 자체가 릴리즈된게 얼마 되지 않았기에 공식문서 튜토리얼에서도 뭔가 헤매게 만든다. 앞뒤가 다르다거나 정보가 애매하게 적혀있는 부분도 있어서 아직 정돈이 안됐다.
아직 일관성이 없다. 어떤 컴포넌트는 함수형이고 어떤 컴포넌트는 화살표형이고 그렇다. 시간이 해결해줄 것이다.
불평불만을 했지만 튜토리얼 1단계를 끝냈다. 다음 튜토리얼도 해보고 이후에 Lynx의 코어 기능들을 하나씩 읽어보면서 기능에 대한 명세, 구현, 배경 지식을 쌓다보면 더 이해가 되는 부분도 있을 것이라 생각이 든다.
일단 더 해봐야겠다. 새로나온 라이브러리라 자료가 없다. 그래서 더 고민하고 찾아봐야하는 장점이 있다. 또한 영어 공부도 조금 된다. 나쁘지 않은 기분이다.
'FrontEnd' 카테고리의 다른 글
[Chrome Extension] HTML, JS로 만든 크롬 확장앱을 React, TS로 마이그레이션 하기 (0) | 2025.05.18 |
---|---|
[Chrome Extension] 크롬 확장앱 일단 만들어보기 (4) | 2025.05.14 |
[Lynx - React] 튜토리얼 따라가기 - Product Gallery (Part 1) (0) | 2025.04.22 |
[Lynx] Quick Start - Lynx 프로젝트를 처음 실행해보자 (0) | 2025.04.20 |
[Lynx] Why Lynx? Lynx가 뭐를 추구할까? (4) | 2025.04.16 |