PullToRefresh
당겨서 새로고침. 스크롤러를 감싸지 않고 props 를 돌려준다.
import { PullToRefresh } from '@coldsurfers/surf-ui/native/PullToRefresh'
import { useAnimatedRef } from 'react-native-reanimated'
function Feed() {
const scrollableRef = useAnimatedRef<Animated.FlatList<Event>>()
return (
<PullToRefresh
scrollableRef={scrollableRef}
onRefresh={() => Promise.all([refetchFeed(), refetchBanner()])}
onHapticFeedback={() => Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light)}
>
{(scrollableProps) => (
<Animated.FlatList data={events} renderItem={renderEvent} {...scrollableProps} />
)}
</PullToRefresh>
)
}미리보기가 없는 이유
reanimated 의 워클릿 변환이 babel 플러그인인데, turbopack 은 node_modules 를 babel 대상에서
뺍니다. 이 사이트가 무는 워클릿은 DS 의 dist 안에 있어서 기본 배선이 닿지 않습니다
(#119).
뚫리더라도 제스처는 마우스로 흉내 내면 감각이 거짓이라, 이 표면은 실기기에서 보는 편이 맞습니다.
RN 기본 RefreshControl 을 왜 안 쓰나
그건 iOS UIRefreshControl · Android SwipeRefreshLayout 이 그리는 네이티브 뷰라
자식도 커스텀 인디케이터도 받지 않습니다. 색 채널(tintColor/colors)만 열려 있어서
색을 맞춰 봐야 모양은 플랫폼 것 그대로입니다. 그래서 당김 감지부터 이쪽이 합니다.
스크롤러를 감싸지 않고 돌려주는 이유
화면마다 스크롤러가 다릅니다 — 피드는 SectionList, 목록 화면은 FlatList 입니다.
어느 쪽을 쓸지는 소비처가 정하고, 여기서는 거기 꽂을 props 만 넘깁니다.
받은 props 는 그대로 펼쳐 넣어야 합니다.
| props | 왜 |
|---|---|
ref | 안 달면 "지금 맨 위인가"를 알 수 없어 스크롤 중간에서도 당김이 걸립니다 |
bounces: false | iOS 네이티브 바운스가 켜져 있으면 네이티브가 밀어 올린 만큼 틈에 더해져 두 배로 움직입니다 |
overScrollMode: 'never' | Android 글로우/스트레치도 같은 이유 |
scrollableRef 를 소비처가 만드는 이유
여기서 만들어 children 인자로만 주면, 소비처가 scroll-to-top 같은 다른 용도와 합치려고
렌더마다 새 콜백 ref 를 쓰게 됩니다. 그러면 React 가 매 렌더 ref(null) → ref(node) 를
돌려 당김 판정이 흔들립니다.
Android 에는 오버스크롤 바운스가 없다
스크롤 오프셋이 음수로 내려가지 않으므로 "오프셋이 마이너스면 당김" 이라는 iOS 식 판정이 통째로 안 먹습니다. 그래서 오프셋이 아니라 제스처의 이동량을 재고, 오프셋은 "지금 맨 위인가"를 가르는 데만 씁니다.
onRefresh 는 promise 를 돌려주면 된다
promise 가 끝날 때까지 인디케이터가 떠 있습니다. 화면이 여러 쿼리로 쪼개져 있으면
Promise.all 로 묶어 넘깁니다. 최소 노출 시간은 같이 기다립니다 — 순차로 기다리면
느린 응답에 그만큼이 그대로 얹힙니다.
실패는 삼킵니다. 네트워크가 죽으면 늘 나는 경로라 여기서 안 삼키면 unhandled rejection 이 됩니다. 인디케이터는 닫히고, 에러 표시는 소비처의 몫입니다.
onHapticFeedback 은 왜 콜백인가
DS 가 expo-haptics 를 물면 Expo 를 쓰지 않는 소비처까지 그걸 깔아야 합니다. 무엇을 어떤
세기로 울릴지도 화면의 맥락이라 소비처가 정합니다. 그래서 시점만 여기가 알고, 울리는 건
소비처가 합니다.
성공 · 실패를 가리지 않고 불립니다. "요청이 끝났다"는 신호지 "성공했다"는 신호가 아닙니다.
절대 위치 헤더가 있으면 topInset
헤더가 콘텐츠 위에 떠 있는 화면에서 0 에 열면 인디케이터 스트립이 헤더 뒤에 가립니다. 헤더 높이를 넘기면 그 아래에서 열립니다.
Props
Prop
Type
스크롤러에 펼쳐 넣는 props
Prop
Type