개발자 박가나
[241202 TIL] 본캠프 44일차 (Funnel 패턴) 본문
Funnel 패턴
Funnel은 깔대기를 의미한다. 즉, Funnel 패턴은 마치 깔대기 모양처럼 사용자가 단계를 거치면서 정보를 입력하는 UI 설계 방식을 말한다.
사용자가 여러 정보를 입력할 때, 모든 것을 한 번에 입력하는 것이 아니라 단계를 나눠서 하나씩 처리하기 때문에 깔대기처럼 점점 좁아지는 형식처럼 보인다.
기존 방식
각 단계별로 별도의 컴포넌트를 만들고 전역 상태를 사용해서 데이터를 관리한다. 페이지 간의 이동은 라우터로 처리하고, 최종 단계에서 모든 데이터를 수집해서 API를 호출한다.
- 각 단계가 별도의 파일이나 컴포넌트로 분산되어 있어 흐름 파악이 어려움
- 상태 변경이 여러 컴포넌트에서 이루어지기 때문에 데이터 흐름을 추적하기 어려움
- 코드 수정 시 여러 파일을 수정해야하기 때문에 유지보수가 어려움
- 라우터에 강하게 의존
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>
);
}
Funnel 패턴 방식
Funnel 패턴을 적용하여 상태 관리와 페이지 흐름을 하나의 컴포넌트에서 관리함으로써 기존 방식의 문제점을 해결할 수 있다.
- 상태 관리와 페이지 흐름을 하나의 컴포넌트에서 처리해서 코드가 간결해짐
- 모든 상태 변경이 한 곳에서 이루어지므로 데이터 흐름 추적이 쉬움
- 코드 수정이 쉬움
- 라우팅 없이도 단계 전환 가능
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>
);
}
useFunnel 생성
상태 관리와 페이지 전환 로직을 캡슐화하기 위해서 Custom Hook을 생성해서 사용한다.
import { useState } from 'react';
function useFunnel(initialStep) {
const [currentStep, setCurrentStep] = useState(initialStep);
const Step = ({ name, children }) => {
return <>{children}</>;
};
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 };
}
'내일배움캠프' 카테고리의 다른 글
[241206 TIL] 본캠프 48일차 (Generic과 Utility Type) (1) | 2024.12.06 |
---|---|
[241205 TIL] 본캠프 47일차 (아웃소싱 프로젝트 회고) (0) | 2024.12.05 |
[241129 TIL] 본캠프 43일차 (useInfiniteQuery) (0) | 2024.11.29 |
[241128 TIL] 본캠프 42일차 (HTTP와 HTTPS) (0) | 2024.11.28 |
[241127 TIL] 본캠프 41일차 (TanStack Query 실습) (0) | 2024.11.27 |