본문으로 바로가기
윤창원uiwwsw · 작은 우주

개발과 기술

하나의 UI를 나누어 보여주는 Step 컴포넌트

2026-09-10: 설명과 코드 예시를 보완했습니다. 아래 예시는 글의 설계 의도를 전달하기 위한 것이며, 원 프로젝트에 반영된 변경 내역과는 구분합니다.

회원가입 항목을 PC에서는 한 화면에 놓고, 모바일에서는 몇 단계로 나누고 싶었다. 날짜와 시간도 한꺼번에 입력하거나 순서대로 입력하게 할 수 있다. 표시 방식이 다르다는 이유로 같은 항목을 두 번 만들고 싶지는 않았다. Step 컴포넌트는 그 구분을 맡기 위해 만들었다.

표현 모드를 분리하기

step은 현재 단계의 0부터 시작하는 번호다. showAll이 true이면 모든 단계를 함께 보여준다. 이전 이름인 release는 배포 환경과 혼동될 수 있어 표현 목적이 드러나는 이름으로 바꿨다.

import { Children, type PropsWithChildren } from 'react';
import { AnimatePresence, motion, useReducedMotion } from 'framer-motion';

type StepProps = PropsWithChildren<{ step: number; showAll?: boolean }>;

export function Step({ children, step, showAll = false }: StepProps) {
  const reduceMotion = useReducedMotion();
  const steps = Children.toArray(children);

  if (showAll) return <>{children}</>;
  if (!Number.isInteger(step) || step < 0 || step >= steps.length) return null;

  return (
    <AnimatePresence mode="wait" initial={false}>
      <motion.div
        key={step}
        initial={{ opacity: 0, x: reduceMotion ? 0 : 20 }}
        animate={{ opacity: 1, x: 0 }}
        exit={{ opacity: 0, x: reduceMotion ? 0 : -20 }}
        transition={{ duration: reduceMotion ? 0 : 0.3 }}
      >
        {steps[step]}
      </motion.div>
    </AnimatePresence>
  );
}

Children.toArray는 children을 순회하기 쉽게 만들지만, 컴포넌트가 나중에 렌더링하는 내부나 Fragment 안까지 단계로 펼쳐주지는 않는다. 각 단계를 직접 자식으로 전달하는 계약이 필요하다. React Children

표시를 나누는 것과 상태를 보존하는 것

단계를 바꿨다가 돌아왔을 때 입력했던 값도 남아 있을까. 이 컴포넌트가 고르는 것은 보여줄 단계뿐이다. 이전 단계가 언마운트되면 그 안의 로컬 상태는 사라질 수 있으므로, 폼 데이터는 상위 상태나 폼 모델에서 보관해야 한다.

showAll은 애니메이션만 끄는 옵션이 아니다. 모든 항목을 보여주는 별도의 표현 모드다. 화면 크기에 따라 이 값을 바꾼다면 전환 시의 상태 보존과 SSR 초기 화면도 확인해야 한다.

단계 이동 후 포커스를 어디로 보낼지, 오류가 있는 이전 단계로 어떻게 돌아갈지도 사용자 흐름에서 정해야 한다. 작은 Step 컴포넌트가 유효성 검사와 전체 폼 상태까지 맡을 필요는 없다.

입력 항목은 한 번 정의하고, 화면에 따라 한꺼번에 보이거나 나누어 보이게 한다. Step에는 그 일까지만 맡겼다. 사용자가 어느 단계에 있든 입력한 내용이 이어지는지는 폼을 구성하는 쪽에서 챙긴다.

Assisted by AI

© uiwwsw · 본인 소유의 글·이미지에 대한 무단 복제·재게시를 허용하지 않습니다. 개인 열람·원문 링크 공유·검색 색인과 제한적인 미리보기는 허용합니다. 법령상 이용 예외, 기존 이용 허락, 코드·제삼자 자료의 기존 라이선스는 유지합니다. 콘텐츠 이용 안내

무단 복제·재게시를 허용하지 않습니다. 콘텐츠 이용 안내

윤창원이 벨로그에 남긴 글을 이 작은 우주에도 모았습니다. 사진은 누르면 원본 크기로 볼 수 있습니다. 원문의 전체 서식 보기 ↗

모든 글 둘러보기 →