Docs
마이그레이션 가이드 (v1 → v2)

마이그레이션 가이드: v1 → v2

이 가이드는 Stackflow 2.0의 주요 변경 사항과 v1에서 마이그레이션하는 방법을 다뤄요.

개요

Stackflow 2.0은 액티비티 선언을 React 컴포넌트에서 분리하는 config-first 접근 방식을 도입해요. 이를 통해 프레임워크에 독립적인 로딩과 향상된 타입 안정성을 통해 더 나은 성능을 제공해요.

1단계: @stackflow/config 설치

npm install @stackflow/config

2단계: stackflow.config.ts 파일 생성

액티비티 선언을 config 파일로 분리해요.

변경 전:

stackflow.ts
import { stackflow } from "@stackflow/react";
 
export const { Stack, useFlow } = stackflow({
  transitionDuration: 350,
  activities: {
    HomeActivity,
    MyProfileActivity,
  },
  plugins: [],
});

변경 후:

stackflow.config.ts
import { defineConfig } from "@stackflow/config";
 
export const config = defineConfig({
  activities: [
    { name: "HomeActivity" },
    { name: "MyProfileActivity" },
  ],
  transitionDuration: 350,
});
stackflow.ts
import { stackflow } from "@stackflow/react";
import { config } from "./stackflow.config";
 
export const { Stack } = stackflow({
  config,
  components: {
    HomeActivity,
    MyProfileActivity,
  },
  plugins: [],
});

3단계: historySyncPlugin 업데이트

라우트는 이제 플러그인 옵션 대신 stackflow.config.ts에 선언해요.

변경 전:

historySyncPlugin({
  routes: {
    HomeActivity: "/",
    MyProfileActivity: "/my-profile",
  },
  fallbackActivity: () => "HomeActivity",
})

변경 후:

stackflow.config.ts에서:

defineConfig({
  activities: [
    { name: "HomeActivity", route: "/" },
    { name: "MyProfileActivity", route: "/my-profile" },
  ],
})

stackflow.ts에서:

historySyncPlugin({
  config,
  fallbackActivity: () => "HomeActivity",
})

4단계: 액티비티 타입 업데이트

타입은 이제 컴포넌트 Props 대신 모듈 augmentation으로 등록해요.

변경 전:

Article.tsx
import type { ActivityComponentType } from "@stackflow/react";
 
type ArticleParams = {
  title: string;
};
 
const Article: ActivityComponentType<ArticleParams> = ({ params }) => {
  // ...
};

변경 후:

Article.tsx
import type { ActivityComponentType } from "@stackflow/react";
 
declare module "@stackflow/config" {
  interface Register {
    Article: {
      title: string;
    };
  }
}
 
const Article: ActivityComponentType<"Article"> = ({ params }) => {
  // params.title의 타입이 자동으로 추론돼요
};

5단계: useFlow, useStepFlow 임포트 업데이트

훅은 이제 팩토리 함수로 생성하는 대신 @stackflow/react에서 직접 import해요.

변경 전:

stackflow.ts
import { stackflow } from "@stackflow/react";
 
export const { Stack, useFlow } = stackflow({
  transitionDuration: 350,
  activities: {
    HomeActivity,
    MyProfileActivity,
  },
  plugins: [],
});
HomeActivity.tsx
import { useFlow } from "./stackflow"; // stackflow() 팩토리에서 import

변경 후:

import { useFlow } from "@stackflow/react"; // 직접 import

이전 useActions() 헬퍼를 참조하던 코드는 @stackflow/react에서 직접 import한 useFlow()로 교체하세요.

6단계: step 내비게이션 메서드 이름 변경

스텝 탐색 함수명이 변경됐어요.

변경 전변경 후
stepPush()pushStep()
stepReplace()replaceStep()
stepPop()popStep()

7단계: <Link /> 임포트 업데이트

<Link /> 컴포넌트는 이제 직접 import해요.

변경 전:

Link.ts
import { createLinkComponent } from "@stackflow/link";
import type { TypeActivities } from "./stackflow";
 
export const { Link } = createLinkComponent<TypeActivities>();

변경 후:

import { Link } from "@stackflow/link";

8단계: 임포트 경로 업데이트

기존 엔트리 포인트를 모두 교체해요.

변경 전변경 후
@stackflow/react/future@stackflow/react
@stackflow/link/future@stackflow/link

삭제된 패키지

v2에서 다음 패키지들이 삭제됐어요.

  • @stackflow/plugin-preload — 빌트인 Loader API를 사용하세요. Loader API 참고.
  • @stackflow/plugin-map-initial-activitydefineConfig()initialActivity를 사용하세요.

삭제된 훅

다음 훅은 더 이상 @stackflow/react에서 export되지 않아요.

v1 훅v2 대체
useActiveEffect(effect)React useEffect에서 useActivity().isActive를 확인하세요. 포커스 전환 시 즉시 실행해야 하는 외부 side-effect는 @stackflow/plugin-lifecycleuseFocusEffect()를 사용하세요.
useEnterDoneEffect(effect, deps)React useEffect에서 useActivity().isToptransitionState === "enter-done"를 확인하세요.
useStep()useActivity()activity.steps를 읽어 루트가 아닌 마지막 step을 계산하세요 (activity.steps.filter((step) => step.id !== activity.id).at(-1) ?? null). 현재 step params만 필요하면 activity/component의 params를 사용하세요.

API 대응표

v1v2
stackflow({ transitionDuration, activities, plugins })stackflow({ config, components, plugins })
ActivityComponentType<Params>ActivityComponentType<"ActivityName">
useActions()@stackflow/reactuseFlow()
stackflow() 팩토리의 useFlow()@stackflow/reactuseFlow()
stackflow() 팩토리의 useStepFlow()@stackflow/reactuseStepFlow()
stepPush/stepReplace/stepPoppushStep/replaceStep/popStep
createLinkComponent<TypeActivities>()import { Link } from "@stackflow/link"
historySyncPlugin({ routes, fallbackActivity })historySyncPlugin({ config, fallbackActivity })
preloadPlugin(...)빌트인 Loader API