Navigation
useNavigate, useParams, useStep
flemo는 세 가지 내비게이션 훅을 제공해요. 각각이 다른 종류의 이동을 담당해요.
useNavigate
const navigate = useNavigate();
navigate.push("/posts/:slug", { slug: "hello" });
navigate.replace("/login");
navigate.pop(); // 한 화면 뒤로
navigate.pop({ skip: 2 }); // 두 화면 뒤로, 한 번의 전환으로
navigate.pop({ until: "/posts/:slug" }); // 가장 가까운 일치 화면까지 뒤로
navigate.pop({ until: "/", transitionName: "cupertino" }); // 뒤로가기 전환을 직접 지정push·replace·pop은 비동기예요. 전환이 시작되고 라우트가 반영될 때까지 기다려요. 얼마나 멀리 가든
한 번의 전환을 일으켜요.
top 너머로 도달하기
pop·replace·push 모두 선택적으로 거리를 받아요. { skip }(화면 수) 또는 { until }(라우트 패턴).
top 아래의 한 화면까지 한 번의 전환으로 도달하고, 건너뛰는 중간 화면들은 한 프레임도 그려지지 않고
제거돼요. 스쳐 지나가는 게 안 보여요.
{ skip: n }은 top에서 n칸 아래 화면, { until }은 라우트가 패턴과 일치하는 가장 가까운 아래 화면이에요
(top→루트 탐색, 현재 top 제외). 셋은 같은 화면에 도달하고, 거기서 하는 일만 달라요:
| 메서드 | 도달한 화면에서… |
|---|---|
pop | 그 화면에 머물러요. 화면이 남아요 |
replace | 그 화면을 교체. 그 화면과 위 전부가 새 화면이 돼요 |
push | 그 화면을 남기고 위에 새 화면을 쌓아요 |
// 스택: / → /library → /posts/a → /posts/b (top = /posts/b)
navigate.pop({ skip: 2 }); // → /, /library (/library에 머무름)
navigate.replace("/x", {}, { skip: 2 }); // → /, /x (/library 교체)
navigate.push("/x", {}, { skip: 2 }); // → /, /library, /x (/library 유지)
navigate.pop({ until: "/library" }); // → /, /library
navigate.replace("/x", {}, { until: "/library" }); // → /, /x
navigate.push("/x", {}, { until: "/library" }); // → /, /library, /x{ skip }과 { until }은 상호 배타예요(둘 다 주면 until 우선). 일치하는 화면이 없으면 pop/replace는
no-op, push는 그냥 일반 push예요. { skip }은 스택 깊이로 제한돼요.
옵션
navigate.push(
"/posts/:slug",
{ slug: "hello" },
{
transitionName: "material",
layoutId: "photo-hello"
}
);| 옵션 | 동작 |
|---|---|
transitionName | 이번 내비게이션의 전환을 지정. pop에서는 뒤로가기 애니메이션을 지정. 여러 화면을 한 번에 접을 때 맨 위 화면 고유의 전환을 쓰고 싶지 않을 때 유용 |
layoutId | layoutId 모핑 태그. transitionName: "layout"과 함께 push 또는 replace 시 사용 |
skip | top에서 n칸 아래까지 한 번의 전환으로 도달. top 너머로 도달하기 참고 |
until | 라우트 패턴과 일치하는 가장 가까운 아래 화면까지 도달. top 너머로 도달하기 참고 |
skip·until·transitionName은 push·replace·pop 모두에서 받고, layoutId는
push·replace에 적용돼요.
useParams
useParams<T>()는 현재 라우트의 파라미터를 반환해요. 타입은 RegisterRoute augmentation에서
가져와요.
function Post() {
const { slug } = useParams<"/posts/:slug">();
return <h1>{slug}</h1>;
}경로 파라미터와 쿼리 파라미터를 하나의 객체로 합쳐서 돌려줘요.
URL: /posts/hello?ref=home
useParams<"/posts/:slug">() → { slug: "hello", ref: "home" }useStep
useStep()은 현재 화면 안에서 sub-state를 바꿀 때 사용해요. 새 history 엔트리를 push 하기
때문에 브라우저 뒤로가기 버튼도 그대로 동작해요. 다만 라우트 자체는 바뀌지 않아서, 같은
<Screen>이 그대로 유지되고 파라미터만 갱신돼요.
전형적인 사용처는 한 화면 안의 다단계 폼이에요.
function Onboarding() {
const { step = "name" } = useParams<"/onboarding">();
const stepper = useStep<"/onboarding">();
if (step === "name") {
return <button onClick={() => stepper.pushStep({ step: "email" })}>다음</button>;
}
if (step === "email") {
return <button onClick={() => stepper.popStep()}>뒤로</button>;
}
}| 메서드 | 동작 |
|---|---|
pushStep(params) | 같은 라우트에 새 파라미터로 history 엔트리를 추가해요 |
replaceStep(params) | 현재 엔트리를 새 파라미터로 교체해요 |
popStep() | 한 단계 뒤로 가요 (window.history.back()) |
push와 step 중 무엇을 쓸까
| 하고 싶은 동작 | 사용 |
|---|---|
| 다른 화면을 띄우기 | navigate.push |
| 현재 화면을 다른 화면으로 교체 (로그인 → 홈) | navigate.replace |
| 현재 화면을 닫기 | navigate.pop |
| 여러 화면을 한 번에 뒤로 가기 | navigate.pop({ skip }) |
| 특정 이전 화면까지 뒤로 가기 | navigate.pop({ until }) |
| 중간 화면을 치우며 push/replace | …({ skip }) / …({ until }) |
| 같은 화면을 유지한 채 UI만 바꾸기 | useStep().pushStep |
useStep은 화면 트리 안에서 모든 게 유지돼요. 같은 Screen 인스턴스, 같은 Provider, 스크롤
위치까지 그대로예요. useNavigate는 진짜 전환과 함께 새 Screen을 마운트해요.