# Pull To Refresh
URL: /lynx/components/pull-to-refresh
Source: https://github.com/daangn/seed-design/blob/dev/docs/content/lynx/components/pull-to-refresh.mdx
사용자가 화면을 아래로 당겨 콘텐츠를 새로고침하는 컴포넌트입니다.
사용 가능 버전: @seed-design/lynx-react@1.0.0, @seed-design/lynx-css@1.0.0
## Preview
```tsx
import "./styles";
import {
PullToRefreshContent,
PullToRefreshIndicator,
PullToRefreshRoot,
} from "@/components/ui/pull-to-refresh";
import { PARAGRAPH, useRefreshObservation } from "./use-refresh-observation";
export default function Example() {
const { refreshCount, lastEvent, callbacks } = useRefreshObservation();
return (
Pull To Refresh
최상단에서 아래로 당겨보세요. 짧게 당기면 취소되고, 충분히 당긴 뒤 놓으면 1초 동안
새로고침합니다.
{`refresh 횟수: ${refreshCount} · 마지막 이벤트: ${lastEvent}`}
{Array.from({ length: 8 }, (_, index) => (
{`${index + 1}. ${PARAGRAPH}`}
))}
);
}
```
## Installation
- npm: npx @seed-design/cli@latest add ui:pull-to-refresh
- pnpm: pnpm dlx @seed-design/cli@latest add ui:pull-to-refresh
- yarn: yarn dlx @seed-design/cli@latest add ui:pull-to-refresh
- bun: bun x @seed-design/cli@latest add ui:pull-to-refresh
### 요구 사항
SEED의 최소 지원 Lynx Engine은 `3.6`입니다. PullToRefresh는 `@lynx-js/gesture-runtime`의 `NativeGesture`를 사용하므로 앱의 기존 React 플러그인 설정에 `enableNewGesture: true`를 추가하세요.
```ts title="lynx.config.ts"
pluginReactLynx({
engineVersion: "3.6",
enableNewGesture: true,
});
```
`enableNewGesture`의 Since `2.16`은 엔진 설정의 도입 기록입니다. SEED의 최소 지원 엔진을 뜻하지 않습니다. 설정 위치와 생략 조건은 [Feature Flags](/lynx/getting-started/feature-flags#이벤트와-제스처)에서 확인하세요.
## Props
### `PullToRefreshRoot`
`onPtrRefresh`에 새로고침 작업을 반환하는 비동기 함수를 전달하세요. `threshold`의 기본값은 `88`, `displacementMultiplier`의 기본값은 `0.75`입니다. 당긴 변위가 threshold를 넘은 상태에서 놓으면 새로고침을 시작합니다. Promise가 완료되거나 실패하면 콘텐츠가 원래 위치로 돌아옵니다.
### `PullToRefreshIndicator`
고유 prop이 없습니다.
### `PullToRefreshContent`
Content는 세로 ``입니다. Root에 높이를 지정하고 화면의 세로 스크롤은 Content 하나로 구성하세요. 중첩된 세로 스크롤 컨테이너는 당김 제스처와 경합할 수 있습니다.
## Examples
### PTR in Tabs
가로로 넘길 수 있는 Tabs Carousel의 Tab 1에만 PullToRefresh를 배치합니다. Tab 2에서는 새로고침하지 않습니다.
```tsx
import "./styles";
import {
PullToRefreshContent,
PullToRefreshIndicator,
PullToRefreshRoot,
} from "@/components/ui/pull-to-refresh";
import { TabsCarousel, TabsContent, TabsList, TabsRoot, TabsTrigger } from "@/components/ui/tabs";
import { PARAGRAPH, useRefreshObservation } from "./use-refresh-observation";
export default function Example() {
const { refreshCount, lastEvent, callbacks } = useRefreshObservation();
return (
Pull To Refresh
{`Tab 1 refresh 횟수: ${refreshCount} · 마지막 이벤트: ${lastEvent}`}
Tab 1
Tab 2
{PARAGRAPH}
PTR is not available in this tab.
);
}
```
### Disabled
`disabled` 속성으로 PTR을 비활성화할 수 있습니다. 당기는 도중 비활성화하면 당김이 취소됩니다. 이미 시작한 새로고침은 반환한 Promise가 끝날 때까지 유지됩니다.
```tsx
import "./styles";
import { useState } from "@lynx-js/react";
import {
PullToRefreshContent,
PullToRefreshIndicator,
PullToRefreshRoot,
} from "@/components/ui/pull-to-refresh";
import { Switch } from "@/components/ui/switch";
import { useRefreshObservation } from "./use-refresh-observation";
export default function Example() {
const [disabled, setDisabled] = useState(false);
const { refreshCount, lastEvent, callbacks } = useRefreshObservation();
function onCheckedChange(checked: boolean) {
"background only";
setDisabled(checked);
}
return (
Disabled
{`disabled: ${JSON.stringify(disabled)} · refresh 횟수: ${refreshCount} · 마지막 이벤트: ${lastEvent}`}
Disabled
);
}
```
### Prevent Pull
Root 안의 특정 영역에서 당김을 막으려면 `usePullToRefreshPreventPull()`이 반환한 props를 해당 ``에 전달하세요. 같은 요소에 `main-thread:bindtouchstart`를 함께 지정하지 마세요.
```tsx
import "./styles";
import { usePullToRefreshPreventPull } from "@seed-design/lynx-react";
import {
PullToRefreshContent,
PullToRefreshIndicator,
PullToRefreshRoot,
} from "@/components/ui/pull-to-refresh";
import { useRefreshObservation } from "./use-refresh-observation";
function ProtectedRegion() {
const preventPullProps = usePullToRefreshPreventPull();
return (
이 영역은 당겨서 새로고침이 불가능합니다. Aliquip ad amet eu dolore id enim excepteur
laboris officia anim in. Irure irure nulla sit eiusmod aliqua sint excepteur amet laboris.
);
}
function PullableRegion() {
return (
이 영역은 당겨서 새로고침이 가능합니다. Amet in laborum proident fugiat mollit quis aute
mollit esse nostrud. Excepteur ea proident ipsum duis. Nulla Lorem pariatur exercitation
velit anim.
);
}
export default function Example() {
const { refreshCount, lastEvent, callbacks } = useRefreshObservation();
return (
Prevent Pull
{`refresh 횟수: ${refreshCount} · 마지막 이벤트: ${lastEvent}`}
);
}
```
## 웹 버전과의 차이
- Lynx는 Root가 배치와 clipping을 맡고 Content가 세로 스크롤을 담당합니다. `asChild`는 지원하지 않습니다.
- Content 내부의 중첩 스크롤 영역을 자동으로 탐지하지 않습니다.
- 스크롤하다 최상단에 도달한 경우 손을 뗀 뒤 다시 당겨야 새로고침이 시작됩니다.