문서보기
useFunnel()

useFunnel()

useFunnel()은 복잡한 UI 흐름을 간편하게 구현할 수 있도록 도와주는 React Hook (opens in a new tab)이에요. Hook은 React 컴포넌트 내에서 사용할 수 있는 함수에요. Hook을 활용하면 컴포넌트의 상태나 라이프사이클 기능을 관리할 수 있어요.

인터페이스

useFunnel()UseFunnelOptions 옵션을 받고, UseFunnelResults 객체를 반환해요.

function useFunnel<T>(options: UseFunnelOptions<T>): UseFunnelResults<T>;

UseFunnelOptions

퍼널의 초기 상태와 각 단계의 설정을 정의하는 객체에요.

interface UseFunnelOptions<T> {
  id: string;
  initial: { step: keyof T, context: T[keyof T] };
  steps?: { [key in keyof T]?: FunnelStepOption<T[key]> };
}
  • id (string, required): 퍼널의 고유 식별자에요. 이 식별자로 퍼널 인스턴스를 식별하고 관리해요.
  • initial (object, required): 퍼널의 초기 상태를 정의해요. step에는 T 객체의 키가 들어가고, context에는 해당 키의 값이 들어가요.
    • step (string): 초기 단계의 이름이에요.
    • context (object): 초기 단계의 상태를 나타내는 객체에요.
  • steps (object, optional): 각 단계의 옵션을 정의해요. T 객체의 키를 사용하여 FunnelStepOption 객체를 값으로 받아요.

FunnelStepOption

FunnelStepOption은 각 단계의 추가 옵션을 정의하는 인터페이스입니다.

interface FunnelStepOption<TContext> {
  guard?: (data: unknown) => data is TContext;
  parse?: (data: unknown) => TContext;
}
  • guard (function, optional): 데이터를 검증해서 해당 단계의 컨텍스트 타입인지 확인하는 함수입니다.
  • parse (function, optional): 데이터를 받아 해당 단계의 컨텍스트 타입으로 변환하는 함수입니다.

UseFunnelResults

퍼널의 상태와 히스토리를 관리하기 위한 속성과 메서드를 포함합니다.

type UseFunnelResults<T> = {
  [key in keyof T]: {
    step: key
    context: T[key];
    history: FunnelHistory<T, T[key]>;
  }
}[keyof T] & {
  index: number;
  historySteps: { step: keyof T, context: T[keyof T] }[];
  Render: FunnelRenderComponent<T>;
};
  • step (string): 현재 퍼널의 단계를 나타내는 속성이에요. T 객체의 키를 사용해요.
  • context (object): 현재 퍼널의 컨텍스트를 나타내는 속성이에요. step 속성의 값에 따라 정의한 T 객체의 값이 들어가요.
  • history (object): 퍼널의 이동을 관리하는 객체에요. 자세한 내용은 FunnelHistory를 참고하세요.
  • index (number): 현재 퍼널의 단계 인덱스에요. historySteps 배열의 인덱스와 동일해요.
  • historySteps (array): 퍼널의 이동 히스토리를 나타내는 배열에요. 각 요소는 단계의 이름과 컨텍스트를 나타내는 객체에요.
  • <Render /> (function): 렌더링을 위한 컴포넌트에요. 자세한 내용은 <funnel.Render />를 참고하세요.

FunnelHistory

퍼널의 이동을 관리하는 객체에요. 퍼널의 단계 전환을 처리하는 여러 메서드를 포함하고 있어요.

interface FunnelHistory<TContextMap, TCurrentStep extends keyof TContextMap> {
  push: <TTargetStep extends keyof TContextMap>(
    step: TTargetStep,
    context: TContextMap[TTargetStep] | ((prev: TContextMap<TCurrentStep>) => T[TTargetStep]),
    routeOption?: RouteOption
  ) => Promise<void> | void;
  replace: <TTargetStep extends keyof TContextMap>(
    step: TTargetStep,
    context: TContextMap[TTargetStep] | ((prev: TContextMap<TCurrentStep>) => T[TTargetStep]),
    routeOption?: RouteOption
  ) => Promise<void> | void;
  go: (index: number) => void | Promise<void>;
  back: () => void | Promise<void>;
}
  • push (function): 새로운 단계로 이동해요. 이전 단계의 히스토리를 남겨요.
    • step (string): 이동할 단계의 이름이에요.
    • context (object | function): 이동할 단계의 상태를 나타내는 객체에요. 혹은 현재 단계 상태를 이용해서 다음 단계 상태를 만드는 함수를 넣을 수 있어요.
    • routeOption (object): 이동할 단계에다가 설정할 수 있는 라우팅 옵션이에요. 패키지 별로 다른 옵션을 제공이 돼요. 자세한 내용은 하단의 RouteOption을 참고하세요.
  • replace (function): 새로운 단계로 이동해요. 이전 단계의 히스토리를 남기지 않아요.
    • step (string): 이동할 단계의 이름입니다.
    • context (object | function): 이동할 단계의 상태를 나타내는 객체입니다. 혹은 현재 단계 상태를 이용해서 다음 단계 상태를 만드는 함수를 넣을 수 있어요.
    • routeOption (object): 이동할 단계에다가 설정할 수 있는 라우팅 옵션이에요. 패키지 별로 다른 옵션을 제공이 돼요. 자세한 내용은 하단의 RouteOption을 참고하세요.
  • go (function): 현재 인덱스 기준으로 지정된 단계로 이동해요.
    • index (number): 이동하려는 단계의 인덱스에요. 현재 단계로부터의 상대적인 위치를 나타내요.
  • back (function): 이전 단계로 이동해요.

RouteOption

interface RouteOption {
  scroll?: boolean;
  locale?: string;
  shallow?: boolean;
}

자세한 내용은 해당 패키지의 문서 (opens in a new tab)를 참고하세요.

💡

@use-funnel/next 에서는 의도적으로 shallow 옵션의 기본 값을 true 로 설정하고 있어요.

예시

기본 예시

import { useFunnel, UseFunnelOptions, UseFunnelResults } from "@use-funnel/next";
 
type T = {
  helloStep: { message: string; };
  worldStep: { message: string; message2: string }
}
 
const funnel: UseFunnelResults<T> = useFunnel<T>({
  id: "use-funnel-api-reference",
  steps: {},
  initial: {
    step: "helloStep",
    context: {
      message: 'Hello'
    }
  },
} satisfies UseFunnelOptions<T>);

히스토리 관리 예시

import { useFunnel } from "@use-funnel/next";
 
type T = {
  helloStep: { message: string; };
  worldStep: { message: string; message2: string }
}
 
const funnel = useFunnel<T>({
  id: "use-funnel-history-example",
  steps: {},
  initial: {
    step: "helloStep",
    context: {
      message: 'Hello'
    }
  },
});
 
if (funnel.step === 'helloStep') {
  funnel.history.push('worldStep', { message2: 'World' });
}