..TIL 파일 날라가서...
결국 나중에서야 다시 정리한 me의 TIL..
작성.. 해야겠지?
가보자고.
챌린지반 강의정리 - 퍼널(Funnel) 패턴 알아보기
깔끔한 UX 설계하기 (like 토스!)
퍼널 패턴(Funnel Pattern)
퍼널(Funnel) = 깔대기
사용자가 단계를 거쳐 정보를 입력하도록 설계한 UI 패턴
각 단계에서 하나의 정보를 입력 후, 다음 단계로 자연스럽게 이동하는 구조
UI/UX와 코드 품질 모두를 향상시킬 수 있는 강력한 설계 방식
- 특징
- 단계별 UI 분리: 한 번에 하나의 정보만 입력
- 시각적인 단순함: 간결한 화면으로 사용자 스트레스 감소
- 유연한 데이터 관리: 각 단계의 데이터를 독립적으로 처리
- 기존 방식(다단계 폼)의 문제점
- 흩어진 페이지 흐름: 각 단계가 별도의 컴포넌트에 분산되어 흐름 파악 어려움
- 분산된 상태 관리: 여러 컴포넌트에서 상태를 관리하여 복잡한 데이터 흐름을 보임
- 유지보수성 저하: 새로운 단계 추가 시 많은 파일 수정 필요
- 라우터 의존성: 복잡한 라우팅 로직 필요
- 예시코드
import { useState } from "react";
import { BrowserRouter as Router, Route, Switch, useHistory } from "react-router-dom";
function Registration() {
const [userData, setUserData] = useState({});
const history = useHistory();
return (
<Router>
<Switch>
<Route path="/step1">
<Step1
onNext={(data) => {
setUserData({ ...userData, ...data });
history.push("/step2");
}}
/>
</Route>
<Route path="/step2">
<Step2
onNext={(data) => {
setUserData({ ...userData, ...data });
history.push("/step3");
}}
/>
</Route>
<Route path="/final">
<FinalStep onSubmit={() => apiCall(userData)} />
</Route>
</Switch>
</Router>
);
}
토스 퍼널 패턴 접근 방식
상태 관리와 페이지 흐름을 한 곳에서 처리 → 코드 응집도 및 유지보수성 향상
- 주요 특징
- 단계별 흐름, 단일 컴포넌트에서 관리 → 응집도 향상
- 상태 변경이 일원화되어 데이터 흐름을 쉽게 추적
- 라우터 의존성 제거: 라우터 없이 단계 전환 관리
- 가독성 증가 : 코드가 간결하고 이해하기 쉬움
- 유지보수성 및 재사용성 강화 : 단계 추가 및 수정 용이 + 여러 프로젝트에서 활용 가능
- 개선 코드 예시
import { useState } from "react";
function Registration() {
const [userData, setUserData] = useState({});
const [step, setStep] = useState("가입방식");
const handleNext = (data, nextStep) => {
setUserData((prev) => ({ ...prev, ...data }));
setStep(nextStep);
};
return (
<div>
{step === "가입방식" && <SignUpMethod onNext={(data) => handleNext(data, "주민번호")} />}
{step === "주민번호" && <ResidentNumber onNext={(data) => handleNext(data, "주소입력")} />}
{step === "주소입력" && <AddressInput onNext={(data) => handleNext(data, "가입성공")} />}
{step === "가입성공" && <SuccessPage userData={userData} />}
</div>
);
}
코드 개선: 재사용성과 가독성 향상
1. Step 컴포넌트 도입
- Step 컴포넌트를 활용, 조건부 렌더링 간결하게 처리
function Step({ name, currentStep, children }) {
return name === currentStep ? <>{children}</> : null;
}
function Registration() {
const [userData, setUserData] = useState({});
const [step, setStep] = useState("가입방식");
const handleNext = (data, nextStep) => {
setUserData((prev) => ({ ...prev, ...data }));
setStep(nextStep);
};
return (
<div>
<Step name="가입방식" currentStep={step}>
<SignUpMethod onNext={(data) => handleNext(data, "주민번호")} />
</Step>
<Step name="주민번호" currentStep={step}>
<ResidentNumber onNext={(data) => handleNext(data, "주소입력")} />
</Step>
<Step name="주소입력" currentStep={step}>
<AddressInput onNext={(data) => handleNext(data, "가입성공")} />
</Step>
<Step name="가입성공" currentStep={step}>
<SuccessPage userData={userData} />
</Step>
</div>
);
}
2. 커스텀 훅 useFunnel 생성
- 단계 상태 관리 및 페이지 전환 로직 캡슐화
import { useState } from "react";
function useFunnel(initialStep) {
const [currentStep, setCurrentStep] = useState(initialStep);
const Step = ({ name, children }) => {
return name === currentStep ? <>{children}</> : null;
};
const Funnel = ({ children }) => {
const steps = React.Children.toArray(children).filter((child) => child.type === Step);
const activeStep = steps.find((child) => child.props.name === currentStep);
return activeStep || null;
};
const next = (nextStep) => setCurrentStep(nextStep);
const prev = (prevStep) => setCurrentStep(prevStep);
return { Funnel, Step, next, prev, currentStep };
}
- useFunnel 적용한 최종 코드
function Registration() {
const { Funnel, Step, next, prev, currentStep } = useFunnel("가입방식");
const [userData, setUserData] = useState({});
const handleNext = (data, nextStep) => {
setUserData((prev) => ({ ...prev, ...data }));
next(nextStep);
};
return (
<Funnel>
<Step name="가입방식">
<SignUpMethod onNext={(data) => handleNext(data, "주민번호")} />
</Step>
<Step name="주민번호">
<ResidentNumber onNext={(data) => handleNext(data, "주소입력")} onPrev={() => prev("가입방식")} />
</Step>
<Step name="주소입력">
<AddressInput onNext={(data) => handleNext(data, "가입성공")} onPrev={() => prev("주민번호")} />
</Step>
<Step name="가입성공">
<SuccessPage userData={userData} />
</Step>
</Funnel>
);
}
추가 고려 사항
1. URL 동기화
- URL을 단계 상태와 동기화하여 새로고침이나 뒤로 가기 버튼을 눌러도 현재 단계를 유지합니다.
2. 애니메이션 효과
- react-transition-group를 활용하여 단계 전환 시 부드러운 애니메이션을 적용합니다.
마무리 - 주말엔 풀코딩.
오래간만에 쭉 편히 자고
하루는 좀 놀다가
SPA 프로젝트 하고~ 그래야겠다..
그럼 20000.
오늘의 KPT 회고
Keep: 그래도 나름.. 다 했다..
Problem: 다음 거.. 잘 따라갈 수 있을까?
Try: 일단 리액트 빠2
THE_END
'React TIL' 카테고리의 다른 글
[React] Day_58 데일리 정리 (0) | 2024.12.10 |
---|---|
[React] Day_57 데일리 정리 (1) | 2024.12.09 |
[React] Day_55 팀 프로젝트 후기 (4) | 2024.12.05 |
[React] Day_54 팀 프로젝트 작업 관련 트러블슈팅 (2) (0) | 2024.12.04 |
[React] Day_53 팀 프로젝트 작업 관련 트러블슈팅 (1) (0) | 2024.12.03 |