๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป dev

ํ† ์Šคใ…ฃSLASH 23 - ํผ๋„ : ์Ÿ์•„์ง€๋Š” ํŽ˜์ด์ง€ ํ•œ ๋ฐฉ์— ๊ด€๋ฆฌํ•˜๊ธฐ (TOSH | SLASH 23 - Funnel Pattern : Organizing an overflow of pages at once)

โš ๏ธ ์ €์ž‘๊ถŒ ๋ณดํ˜ธ๋ฅผ ์œ„ํ•ด ์ž๋ฃŒ ๋ฐ ์˜ˆ์‹œ๊ฐ€ ๋Œ€์ฒด๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ ์ฝ”๋“œ๋Š” Reactโš›๏ธ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
๐Ÿซจ ํ†ต์‹ ์‚ฌ ๊ฐ€์ž…์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ธด ํผ๊ณผ ์•ฝ์ •์ด ํฌํ•จ๋œ ํŽ˜์ด์ง€๋ฅผ ๋งˆ์ฃผ์น˜๊ฒŒ ๋  ๋•Œ๊ฐ€ ์žˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋งŽ์€ ํŽ˜์ด์ง€๋“ค์„ ๋„˜๋‚˜๋“œ๋Š” ํ๋ฆ„์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ญ˜๊นŒ?
์ด๋ฒˆ๊ธ€์—์„œ๋Š” ํ† ์Šค SLASH23์—์„œ ๋‹ค๋ฃฌ ํผ๋„์„ ํ†ตํ•œ ๋ถ„๊ธฐ์™€ ์ƒํƒœ ๊ด€๋ฆฌ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์ž.

'ํ”Œ๋žซํผ ๋””์ž์ด๋„ˆ๊ฐ€ ํšจ์œจ์„ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๋ฒ•'์—์„œ ์†Œ๊ฐœํ•œ ํ™”๋ฉด ํ๋ฆ„

์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•  ๋•Œ ๋Œ€ํ‘œ์ ์ธ ํ”„๋ก ํŠธ์—”๋“œ ํŒจํ„ด๋“ค

1. ์ƒ์ 

์ƒ์  ํŒจํ„ด

 

๋ชฉ๋ก ํŽ˜์ด์ง€ -> ์ƒ์„ธ ํŽ˜์ด์ง€ ๊ตฌ์กฐ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๊ณ , ๋ธ”๋กœ๊ทธ๋‚˜ ๋‰ด์Šค, To-do ๋ฆฌ์ŠคํŠธ๋„ ์ด ์œ ํ˜•์— ํ•ด๋‹น๋œ๋‹ค.

 

2. ๋‹จ์ผ ํŽ˜์ด์ง€

๋‹จ์ผ ํŽ˜์ด์ง€ ํŒจํ„ด

 

ํŽ˜์ด์ง€ ์ด๋™ ์—†์ด ํ•œ ํ™”๋ฉด ๋‚ด์—์„œ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์ง€๋„๋‚˜ ๋ฉ”์‹ ์ € ์•ฑ์ด ์ด ์œ ํ˜•์— ํ•ด๋‹น๋œ๋‹ค.

 

3. ์„ค๋ฌธ์กฐ์‚ฌ

์„ค๋ฌธ ์กฐ์‚ฌ ํŒจํ„ด

 

์—ฌ๋Ÿฌ ํŽ˜์ด์ง€๋“ค์„ ํ†ตํ•ด ์ƒํƒœ๋ฅผ ์ˆ˜์ง‘ -> ๊ฒฐ๊ณผ ํŽ˜์ด์ง€๋กœ ์ด๋ฃจ์–ด์ง„ ํ˜•ํƒœ, ํšŒ์›๊ฐ€์ž… mbti ๊ฒ€์‚ฌ, ๊ฒฐ์ œ ์‹ ์ฒญ์„œ ๋“ฑ์ด ์ด ์œ ํ˜•์— ํ•ด๋‹น๋œ๋‹ค. ์˜ค๋Š˜ ํ•ต์‹ฌ์ ์œผ๋กœ ๋‹ค๋ฃฐ ํŒจํ„ด์€ "์„ค๋ฌธ์กฐ์‚ฌ ํŒจํ„ด"์ด๊ณ , ํ† ์Šค์—์„œ๋Š” ์ด๋ฅผ 'ํผ๋„(funnel)'ํŒจํ„ด์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

 

funnel์€ '๊น”๋Œ€๊ธฐ'๋ฅผ ๋œปํ•œ๋‹ค. ๊น”๋•Œ๊ธฐ์— ๋ชจ๋ž˜๋ฅผ ๋ถ€์œผ๋ฉด ๊ณ ์€ ์ž…์ž๋Š” ํ†ต๊ณผํ•˜๊ณ  ๊ตต์€ ์ž…์ž๋Š” ํ•„ํ„ฐ ๋˜๋“ฏ์ด, 

๋‹ค์–‘ํ•œ ์œ ์ €๋“ค์ด ์„œ๋น„์Šค์— ์ฒ˜์Œ ๋“ค์–ด๊ฐ€๋ฉด์„œ๋ถ€ํ„ฐ ์ตœ์ข… ๋ชฉํ‘œ์— ๋„๋‹ฌํ•˜๊ธฐ๊นŒ์ง€ ์กฐ๊ธˆ์”ฉ ํ•„ํ„ฐ ๋œ๋‹ค.

 

ํผ๋„ ํŒจํ„ด ๊ตฌํ˜„ ๋ฐฉ์‹

 

๐Ÿ“  ํผ๋„ ๊ตฌ์กฐ๋กœ ํŽ˜์ด์ง€๋ฅผ ๋„˜์–ด๊ฐ€๋ฉด์„œ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ํ๋ฆ„์€ ์œ ์‚ฌํ•˜์—ฌ SKT USIM ์˜จ๋ผ์ธ ๊ฐœํ†ตํŽ˜์ด์ง€๋ฅผ ๊ฐ„๋žตํ™”ํ•œ ์˜ˆ์‹œ๋กœ ๋Œ€์ฒดํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ „๋ฐ˜์ ์ธ ๋””์ž์ธ ์š”๊ตฌ์‚ฌํ•ญ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

๋‹จ๊ณ„๋ณ„๋กœ ์‚ดํŽด๋ณด์ž๋ฉด, 

 

 

์‹ ๊ทœ ๊ฐ€์ž…์„ ์„ ํƒํ•˜๊ณ  ๋‹ค์Œ์œผ๋กœ ์ง„์ž…ํ•˜๊ฒŒ ๋˜๋ฉด 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1 ๋‹จ๊ณ„ : ํ†ต์‹  ์œ ํ˜•์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ stepSeq=1์—์„œ ์ˆ˜์ง‘ํ•˜๊ณ ,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2 ๋‹จ๊ณ„ : ์š”๊ธˆ์ œ ์„ ํƒ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ stepSeq2 ๋‹จ๊ณ„์—์„œ ์ˆ˜์ง‘ํ•œ๋‹ค.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3 ๋‹จ๊ณ„ : ์„ ํƒํ•œ ์š”๊ธˆ์ œ์— ๋”ฐ๋ผ ์ง€๋ถˆํ•ด์•ผ ํ•˜๋Š” ์š”๊ธˆ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๊ณ ,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4 ๋‹จ๊ณ„ :  ์„ ํƒํ•œ ์š”๊ธˆ์ œ์— ๋”ฐ๋ฅธ ํ˜œํƒ ์„ ํƒ ์ •๋ณด๋ฅผ stepSeq=4์—์„œ ์ˆ˜์ง‘ํ•œ๋‹ค.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5 ๋‹จ๊ณ„: ์œ ์ €์˜ ๊ฐœ์ธ ์ •๋ณด๋ฅผ stepSeq=5์—์„œ ์ˆ˜์ง‘ํ•˜๊ณ ,

๊ฐ€์ž… API๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ 1~5์—์„œ ์ˆ˜์ง‘ํ•œ ๋ฐ์ดํ„ฐ (ํ†ต์‹  ์œ ํ˜•/์š”๊ธˆ์ œ ์„ ํƒ/ ํ˜œํƒ ์„ ํƒ/ ๊ฐœ์ธ ์ •๋ณด)๋ฅผ

๋„˜๊ธฐ๋ฉด ๊ฐ€์ž… ์™„๋ฃŒ๐Ÿฅณ

 

 

 

 

 

 

 

 

 

 

 

๐Ÿค” ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ํ•ด๋‹น ํ๋ฆ„์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

๊ธฐ๋ณธ ๊ตฌ์กฐ๋กœ ์„ค๊ณ„

๋จผ์ € ํŽ˜์ด์ง€ ๋ณ„๋กœ ํŒŒ์ผ์„ ๊ตฌ์„ฑํ•ด ๋ณด๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

๐Ÿ—‚๏ธ USIM ์‹ ๊ทœ ๊ฐ€์ž… (/buyproc) 
ใ„ด ๐Ÿ“„ ํ†ต์‹ ์œ ํ˜•.tsx (/net-typ?stepSeq=1)
ใ„ด ๐Ÿ“„ ์š”๊ธˆ์ œ.tsx (/charge?stepSeq=2)
ใ„ด ๐Ÿ“„ ์š”๊ธˆํ™•์ธ.tsx (/condition?stepSeq=3)
ใ„ด ๐Ÿ“„ ํ˜œํƒ.tsx (/benf?stepSeq=4)
ใ„ด ๐Ÿ“„ ๊ฐœ์ธ์ •๋ณด.tsx (/self-auth?stepSeq=5)
ใ„ด ๐Ÿ“„ ๊ฐ€์ž…์™„๋ฃŒ.tsx 

 

๊ฐ ํŽ˜์ด์ง€์— ํ•ด๋‹น๋˜๋Š” ํŒŒ์ผ๋“ค์„ ๋งŒ๋“ค๊ณ , router.push('/${๋‹ค์ŒํŽ˜์ด์ง€ ์ฃผ์†Œ}')๋กœ ๋‹ค์Œ ํŽ˜์ด์ง€๋กœ ์ด๋™์‹œํ‚จ๋‹ค.

๊ฐ ํŽ˜์ด์ง€์— ํ•„์š”ํ•œ ์ƒํƒœ๊ฐ€ ๋‚˜๋ˆ ์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ „์—ญ ์ƒํƒœ  const [registerData, updateRegisterData] = useGlobalState(registerData)๋กœ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋™์ž‘๋„ ์ž˜ ๋˜๋Š” ๊ดœ์ฐฎ์€ ์„ค๊ณ„์ง€๋งŒ, ์œ ์ง€๋ณด์ˆ˜์˜ ์ธก๋ฉด์—์„œ๋Š” ๊ฐœ์„ ํ•  ๋ถ€๋ถ„์ด ๋ณด์ธ๋‹ค.

 

( 1 ) ํŽ˜์ด์ง€ ํ๋ฆ„์ด ์ง๊ด€์ ์ด์ง€ ์•Š๋‹ค.

       - ํ†ต์‹ ์œ ํ˜•.tsx, ์š”๊ธˆ์ œ.tsx, ์š”๊ธˆํ™•์ธ.tsx, ํ˜œํƒ.tsx, ๊ฐœ์ธ์ •๋ณด.tsx, ๊ฐ€์ž…์™„๋ฃŒ.tsx ์ด ํŽ˜์ด์ง€๋“ค์˜ ํ๋ฆ„์„ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”  router.push('/${๋‹ค์ŒํŽ˜์ด์ง€ ์ฃผ์†Œ}')์„ ํƒ€๊ณ  ๊ฐ€๋ฉด์„œ 5๊ฐœ์˜ ํŽ˜์ด์ง€๋“ค์„ ๋“ค์–ด๊ฐ€์„œ ๋ด์•ผ ํŒŒ์•…์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

(2) ์ƒํƒœ๊ฐ€ ์—ฌ๊ธฐ์ €๊ธฐ ํฉ์–ด์ ธ ์žˆ์–ด์„œ ๋””๋ฒ„๊น…์ด ์–ด๋ ค์›Œ์ง€๊ณ  api์— ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๊ฐ€ ๊นŒ๋‹ค๋กญ๋‹ค.

       - ๊ฐ€์ž…์„ ์œ„ํ•œ ์ •๋ณด๋“ค์„ ์ „์—ญ ์ƒํƒœ๋กœ ๊ฐ ํŽ˜์ด์ง€์—์„œ ์ˆ˜์ง‘ํ–ˆ์ง€๋งŒ, api ์ „์†ก์„ ์œ„ํ•ด ์ „์—ญ์ƒํƒœ์˜ ์‚ฌ์šฉ๋˜๋Š” ๊ณณ์€ ๊ฐœ์ธ์ •๋ณด.tsx๋‹ค.

       - ๋””๋ฒ„๊น…์„ ์œ„ํ•ด ๊ฐœ์ธ์ •๋ณด.tsx ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ „์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์ถ”์ ํ•ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค.

 

์ด๋Ÿฐ ๋ฌธ์ œ๋“ค์€ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„๊นŒ?


ํผ๋„ ํŒจํ„ด ์ฝ”๋“œ ๊ฐœ์„  ๋ฐฉ๋ฒ• 3๊ฐ€์ง€

ํผ๋„ ํŒจํ„ด ์ฝ”๋“œ๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•œ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๊ธฐ์ดˆ์ ์ธ ๋ถ€๋ถ„์—์„œ ๋จผ์ € ์‚ดํŽด๋ณธ๋‹ค.
1. ์‘์ง‘๋„

2. ์ถ”์ƒํ™”
3. ์‹œ๊ฐํ™”
๐Ÿ‘ฉ๐Ÿป‍๐Ÿ”ง ๊ฐœ์„  ๋ฐฉํ–ฅ 1: ์—ฐ๊ด€๋œ ์ฝ”๋“œ๋Š” ๊ฐ€๊นŒ์šด ๊ณณ์— ๋ฐฐ์น˜ํ•˜์—ฌ ํฉ์–ด์ ธ ์žˆ๋Š” ์ƒํƒœ์™€ ํŽ˜์ด์ง€๋“ค์„ ํ•œ ๊ณณ์œผ๋กœ ๋ชจ์œผ๊ธฐ!  โžก๏ธ ์‘์ง‘๋„ ๋†’์ด๊ธฐ

 

 const [registerData, updateRegisterData] =useGlobalState(registerData) ์ง€์—ญ ์ƒํƒœ ๋งŒ๋“ค๊ณ , step ์ƒํƒœ์— ๋”ฐ๋ผ UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋งํ•œ๋‹ค.

const [registerData, updateRegisterData] = useState();

const [step, setStep] = useState<
"ํ†ต์‹ ์œ ํ˜•" | "์š”๊ธˆ์ œ" | "์š”๊ธˆํ™•์ธ" | "ํ˜œํƒ" | "๊ฐœ์ธ์ •๋ณด" | "๊ฐ€์ž…์™„๋ฃŒ"
>("ํ†ต์‹ ์œ ํ˜•");

return (
<main>
{step === "ํ†ต์‹ ์œ ํ˜•" && <ํ†ต์‹ ์œ ํ˜• onNext={(data) => setStep("์š”๊ธˆ์ œ")} />}
{step === "์š”๊ธˆ์ œ" && <์š”๊ธˆ์ œ onNext={(data) => setStep("์š”๊ธˆํ™•์ธ")} />}
{step === "์š”๊ธˆํ™•์ธ" && <์š”๊ธˆํ™•์ธ onNext={(data) => setStep("ํ˜œํƒ")} />}
{step === "ํ˜œํƒ" && <ํ˜œํƒ onNext={(data) => setStep("๊ฐœ์ธ์ •๋ณด")} />}
{step === "๊ฐœ์ธ์ •๋ณด" && <๊ฐœ์ธ์ •๋ณด onNext={(data=> setStep("๊ฐ€์ž…์™„๋ฃŒ")} />}
{step === "๊ฐ€์ž…์™„๋ฃŒ" && <๊ฐ€์ž…์™„๋ฃŒ />}
</main>
);

 

๊ฐ ๋‹จ๊ณ„์—์„œ   ๋‹ค์Œ  ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด step ์ƒํƒœ๋ฅผ ์›ํ•˜๋Š” UI๋กœ ์—…๋ฐ์ดํŠธํ•˜์—ฌ,

UI ์„ธ๋ถ€ ์‚ฌํ•ญ์€ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ด€๋ฆฌํ•˜๊ณ , step์˜ ์ด๋™์€ ์ƒ์œ„์—์„œ ๊ด€๋ฆฌํ•˜์—ฌ ํ•œ ๊ณณ์—์„œ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

 

api ํ˜ธ์ถœ์— ํ•„์š”ํ•œ ์ƒํƒœ๋„ ์ƒ์œ„์—์„œ ๊ด€๋ฆฌํ•ด์ฃผ๋ฌด๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ด ์ค„ ๊ฒฝ์šฐ, ์–ด๋–ค UI์—์„œ ์ •๋ณด๊ฐ€ ์ˆ˜์ง‘๋˜๋Š”์ง€

ํŽ˜์ด์ง€๋ฅผ ํƒ€๊ณ  ๊ฐˆ ํ•„์š” ์—†์ด ๋ฐ”๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

{step === "๊ฐœ์ธ์ •๋ณด" && (
    <๊ฐœ์ธ์ •๋ณด
       onNext={async () => {
           await fetch("/api/register", { data });
          setStep("๊ฐ€์ž…์™„๋ฃŒ");
       }}
    />
)}

 

๋˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ค๋ฅธ api๋ฅผ ์ถ”๊ฐ€ํ•˜๋”๋ผ๋„ ์†์‰ฝ๊ฒŒ ๋„์ž…์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

const [registerData, updateRegisterData] = useState();

const [step, setStep] = useState<
  "ํ†ต์‹ ์œ ํ˜•"
| "์š”๊ธˆ์ œ"
| "์š”๊ธˆํ™•์ธ"
| "ํ˜œํƒ"
| "๊ฐœ์ธ์ •๋ณด"
| "ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€"
| "๊ฐ€์ž…์™„๋ฃŒ"
>("ํ†ต์‹ ์œ ํ˜•");

return (
     <main>
         {step === "ํ†ต์‹ ์œ ํ˜•" && <ํ†ต์‹ ์œ ํ˜• onNext={(data) => setStep("์š”๊ธˆ์ œ")} />}
         {step === "์š”๊ธˆ์ œ" && <์š”๊ธˆ์ œ onNext={(data) => setStep("์š”๊ธˆํ™•์ธ")} />}
         {step === "์š”๊ธˆํ™•์ธ" && <์š”๊ธˆํ™•์ธ onNext={(data) => setStep("ํ˜œํƒ")} />}
         {step === "ํ˜œํƒ" && <ํ˜œํƒ onNext={(data) => setStep("๊ฐœ์ธ์ •๋ณด")} />}
         {step === "๊ฐœ์ธ์ •๋ณด" && <๊ฐœ์ธ์ •๋ณด onNext={() => setStep("ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€")} />}
         {step === "ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€" && (         
                  <ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€
                           onNext={async () => {
                                        await fetch("/api/register", { data });
                                        setStep("๊ฐ€์ž…์™„๋ฃŒ");
                           }}/>
           )}
         {step === "๊ฐ€์ž…์™„๋ฃŒ" && <๊ฐ€์ž…์™„๋ฃŒ />}
      </main>
);
 

๐Ÿ‘ฉ๐Ÿป‍๐Ÿ”ง ๊ฐœ์„  ๋ฐฉํ–ฅ 2: ๋‹ค๋ฅธ ํผ๋„์—์„œ๋„ ์ด ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค  โžก๏ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ถ”์ƒํ™”ํ•˜๊ธฐ

 

const [registerData, updateRegisterData] = useState();

const [step, setStep] = useState<
| "ํ†ต์‹ ์œ ํ˜•"
| "์š”๊ธˆ์ œ"
| "์š”๊ธˆํ™•์ธ"
| "ํ˜œํƒ"
| "๊ฐœ์ธ์ •๋ณด"
| "ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€"
| "๊ฐ€์ž…์™„๋ฃŒ"
>("ํ†ต์‹ ์œ ํ˜•"); // step ๊ด€๋ จ ๋กœ์ง

return (
     <main>
         // step ๊ด€๋ จ ๋กœ์ง๋“ค
         {step === "ํ†ต์‹ ์œ ํ˜•" && <ํ†ต์‹ ์œ ํ˜• onNext={(data) => setStep("์š”๊ธˆ์ œ")} />}
         {step === "์š”๊ธˆ์ œ" && <์š”๊ธˆ์ œ onNext={(data) => setStep("์š”๊ธˆํ™•์ธ")} />}
         {step === "์š”๊ธˆํ™•์ธ" && <์š”๊ธˆํ™•์ธ onNext={(data) => setStep("ํ˜œํƒ")} />}
         {step === "ํ˜œํƒ" && <ํ˜œํƒ onNext={(data) => setStep("๊ฐœ์ธ์ •๋ณด")} />}
         {step === "๊ฐœ์ธ์ •๋ณด" && <๊ฐœ์ธ์ •๋ณด onNext={() => setStep("ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€")} />}
         {step === "ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€" && (         
                  <ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€
                           onNext={async () => {
                                        await fetch("/api/register", { data });
                                        setStep("๊ฐ€์ž…์™„๋ฃŒ");
                           }}/>
           )}
         {step === "๊ฐ€์ž…์™„๋ฃŒ" && <๊ฐ€์ž…์™„๋ฃŒ />}
      </main>
);

 

์œ„์—์„œ ์ž‘์„ฑํ–ˆ๋˜ ์ฝ”๋“œ์—์„œ step์˜ ์กฐ๊ฑด์— ๋”ฐ๋ผ์„œ ๋ Œ๋”๋ง์„ ํ•œ๋‹ค๋Š” ๊ณตํ†ต ๋กœ์ง์„ ์ถ”์ƒํ™”ํ•ด ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

// ์‚ฌ์šฉ
<Step if={step === "ํ†ต์‹ ์œ ํ˜•"}>
	<ํ†ต์‹ ์œ ํ˜• onNext={() => setStep("์š”๊ธˆ์ œ")}/>
</Step>

// ๊ตฌํ˜„
function Step({ if, children }){
    if(if === true){
        return children
    }
	return null
}

 

๊ทธ๋Ÿผ ์ „์ฒด ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. 

const [registerData, updateRegisterData] = useState();

const [step, setStep] = useState<
  | "ํ†ต์‹ ์œ ํ˜•"
  | "์š”๊ธˆ์ œ"
  | "์š”๊ธˆํ™•์ธ"
  | "ํ˜œํƒ"
  | "๊ฐœ์ธ์ •๋ณด"
  | "ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€"
  | "๊ฐ€์ž…์™„๋ฃŒ"
>("ํ†ต์‹ ์œ ํ˜•");

return (
  <main>
  	<Step if={step === "ํ†ต์‹ ์œ ํ˜•"}>
    	<ํ†ต์‹ ์œ ํ˜• onNext={(data) => setStep("์š”๊ธˆ์ œ")} />
    </Step>
    <Step if={step === "์š”๊ธˆ์ œ"}>
    	<์š”๊ธˆ์ œ onNext={(data) => setStep("์š”๊ธˆํ™•์ธ")} />
    </Step>
    <Step if={step === "์š”๊ธˆํ™•์ธ"}>
    	<์š”๊ธˆํ™•์ธ onNext={(data) => setStep("ํ˜œํƒ")} />
    </Step>
    <Step if={step === "ํ˜œํƒ"}>
    	<ํ˜œํƒ onNext={(data) => setStep("๊ฐœ์ธ์ •๋ณด")} />
    </Step>
    <Step if={step === "๊ฐœ์ธ์ •๋ณด"}>
    	<๊ฐœ์ธ์ •๋ณด onNext={() => setStep("ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€")} />
    </Step>
    <Step if={step === "ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€"}>
    	<ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€
        onNext={async () => {
          await fetch("/api/register", { data });
          setStep("๊ฐ€์ž…์™„๋ฃŒ");
        }}
      	/>
    </Step>
	<Step if={step === "๊ฐ€์ž…์™„๋ฃŒ"}>
    	<๊ฐ€์ž…์™„๋ฃŒ />
    </Step>
  </main>
);

 

๊ณตํ†ต์œผ๋กœ ๋‚˜ํƒ€๋‚˜๋Š” if = {step === ""} ์กฐ๊ฑด๋ฌธ์€ ์ œ๊ฑฐํ•˜๊ณ  step์˜ ์ด๋ฆ„์— ๋”ฐ๋ผ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก name๋งŒ ๋‚จ๊ฒจ๋‘๊ณ ,

<Step name="ํ†ต์‹ ์œ ํ˜•">
	<ํ†ต์‹ ์œ ํ˜• onNext={() => setStep("์š”๊ธˆ์ œ")}/>
</Step>

 

step์˜ ์ƒํƒœ๋ฅผ ๋‹ด์€ ์ปค์Šคํ…€ ํ›…์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค.

 

// ์ปค์Šคํ…€ ํ›…
function useFunnel(){
    const [step, setStep] = useState(); // step ์ƒํƒœ๋ฅผ ๋‚ด๋ถ€๋กœ ์˜ฎ๊น€ 
  
    const Step = (props) => {
    	return <>{props.children}</>
    }
    
    const Funnel = ({children}) => {
    	// name๊ณผ ํ˜„์žฌ step์ด ๋™์ผํ•œ Step๋งŒ ๋ Œ๋”๋ง
    	const targetStep = children.find(childStep => childStep.props.name === step);
        return Object.assign(targetStep, {Step});
    }
    return [Funnel, setStep];
}

// ์‚ฌ์šฉ
const [Funnel, setStep] = useFunnel<"ํ†ต์‹ ์œ ํ˜•"
  | "์š”๊ธˆ์ œ"
  | "์š”๊ธˆํ™•์ธ"
  | "ํ˜œํƒ"
  | "๊ฐœ์ธ์ •๋ณด"
  | "ํ˜œํƒ์ˆ˜์‹ ์—ฌ๋ถ€"
  | "๊ฐ€์ž…์™„๋ฃŒ"
>("ํ†ต์‹ ์œ ํ˜•");

return (
	<Funnel>
    	<Funnel.Step name="์š”๊ธˆ์ œ">
        	<์š”๊ธˆ์ œ onNext={() => setStep("์š”๊ธˆํ™•์ธ")}/>
        </Funnel.Step>
        <Funnel.Step name="์š”๊ธˆํ™•์ธ">
        	<์š”๊ธˆํ™•์ธ onNext={() => setStep("ํ˜œํƒ")}/>
        </Funnel.Step>
        // ...
    </Funnel>

)

 

useFunnel ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด์„œ๋Š” https://www.slash.page/ko/libraries/react/use-funnel/README.i18n Slash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฌธ์„œ์— ๋Œ€ํ•ด์„œ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 


๐Ÿ‘ฉ๐Ÿป‍๐Ÿ”ง ๊ฐœ์„  ๋ฐฉํ–ฅ 3: ๋‹ค๋ฅธ ํผ๋„์—์„œ๋„ ์ด ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค  โžก๏ธ ์‹œ๊ฐํ™”

 

๊ด€๋ จ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ํ•œ ๊ณณ์œผ๋กœ ๋ชจ์•„ ์‘์ง‘๋„๋ฅผ ๋†’์ด๊ณ , ๋ฐ˜๋ณต๋œ ์ฝ”๋“œ๋ฅผ ์ถ”์ƒํ™”ํ•ด์„œ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ด๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๊ฐœ์„ ํ•ด ๋ดค๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์‚ดํŽด๋ณผ ๊ฒƒ์€ ์‹œ๊ฐํ™”๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž์˜ ๊ฒฝํ—˜(DX)์„ ๊ฐœ์„ ํ•ด ๋ณด๋Š” ๊ฒƒ์ด๋‹ค.

 

ํŽ˜์ด์ง€๊ฐ„์— ์˜ฎ๊ฒจ ๋‹ค๋‹ˆ๋ฉด์„œ ํ๋ฆ„์„ ํŒŒ์•…ํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๊ฐœ์„ ํ–ˆ์ง€๋งŒ, ๋ณด์ž๋งˆ์ž ๊ณง๋ฐ”๋กœ ํŽ˜์ด์ง€ ํ๋ฆ„์„ ํŒŒ์•…ํ•˜๊ธฐ๋Š” ์–ด๋ ต๋‹ค. ๊ฒฐ๊ตญ ์ „์ฒด ํ๋ฆ„์„ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด setStep์„ ์ถ”์ ํ•ด ๊ฐ€๋ฉด์„œ ๋ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ด ์•„์ง๋„ ๋‚จ์•„์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์•„๋ž˜์™€ ๊ฐ™์€ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋ถ„๊ธฐ๊ฐ€ ๋˜ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋ฉด ์ถ”์ ํ•˜๋Š”๋ฐ ๋” ๋ˆˆ์„ ํฌ๊ฒŒ ๋œจ๊ณ  ๋ด์•ผํ•œ๋‹ค ๐Ÿ‘€ (ํ”ผ๋กœ๋ˆ„์ ์€ ๋ค)

<Funnel>
    <Funnel.Step name="์š”๊ธˆ์ œ">
        <์š”๊ธˆ์ œ onNext={() => {
        if(clicked==='5G'){
            setStep("5G์š”๊ธˆํ™•์ธ");
        }else {
            setStep("์ผ๋ฐ˜์š”๊ธˆํ™•์ธ");
        }
        }}/>
    </Funnel.Step>
    <Funnel.Step name="์ผ๋ฐ˜์š”๊ธˆํ™•์ธ">
        <์ผ๋ฐ˜์š”๊ธˆํ™•์ธ on={() => setStep("5Gํ˜œํƒ")}/>
    </Funnel.Step>
    <Funnel.Step name="5G์š”๊ธˆํ™•์ธ">
        <5G์š”๊ธˆํ™•์ธ on={() => setStep("์ผ๋ฐ˜ํ˜œํƒ")}/>
    </Funnel.Step>
    // ...
</Funnel>

 

์ด์ „ SKT USIM ์˜จ๋ผ์ธ ๊ฐœํ†ตํŽ˜์ด์ง€ ์˜ˆ์‹œ์— ์‚ดํŽด๋ดค๋“ฏ์ด URL ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋„ ๊ฐ™์ด ๋ณ€๊ฒฝํ•ด์ค˜์•ผ ํ•˜๋‹ˆ ๋””๋ฒ„๊น…์ด ๊นŒ๋‹ค๋กœ์›Œ์ง„๋‹ค.

ํ† ์Šค์—์„œ๋Š” ๊ฐœ๋ฐœ์ž๋“ค์ด ํผ๋„ ํ๋ฆ„์„ ์‹œ๊ฐํ™”ํ•˜๋Š” ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์ธ Funnel Debugger๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

 

funnel debugger ์‚ฌ์šฉ ์˜ˆ์‹œ

 

useFunnel ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์˜ต์…˜์„ ๋„˜๊ธฐ๋ฉด ํ™”๋ฉด ์šฐ์ธก ํ•˜๋‹จ์— ๋™๊ทธ๋ž€ ๋ฒ„ํŠผ์ด ์žˆ๋‹ค.

์ด ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด useFunnel์„ ์‹œ๊ฐํ™”ํ•œ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

Funnel Debugger๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ/ ๋””๋ฒ„๊น… ์†๋„๋ฅผ ๋†’์ผ ์ˆ˜ ์žˆ๊ณ ,

ํผ๋„์„ ์˜๋„ํ•œ ํ๋ฆ„๋Œ€๋กœ ๊ตฌํ˜„ํ–ˆ๋Š”์ง€ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐ˜์˜๋ผ์„œ ์ฒดํฌ๊ฐ€ ํŽธ๋ฆฌํ•˜๋‹ค.

๋˜ํ•œ ๊ฐœ๋ฐœ์ž์™€ ๋น„๊ฐœ๋ฐœ์ž ๋ชจ๋‘์—๊ฒŒ ์ง๊ด€์ ์œผ๋กœ ํŽ˜์ด์ง€ ํ๋ฆ„์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค.


๊ทธ๋Ÿผ Funnel Debugger๋Š” ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์–ด์กŒ์„๊นŒ?

๋‹ค์ด์–ด๊ทธ๋žจ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ :  Mermaid ๐Ÿงœ‍โ™€๏ธ

 

mermaid๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค.

mermaid์˜ ๋ฌธ๋ฒ•์œผ๋กœ ์ž‘์„ฑํ•ด ์ค€ ์ฝ”๋“œ๋ฅผ mermaid.render(id, text)๋ฅผ ํ†ตํ•ด ๋ Œ๋” ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ทธ๋ž˜ํ”„๋กœ ๋งŒ๋“ค์–ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

์ฒซ๋ฒˆ์งธ์—์„œ onBlur๋ฅผ ํ•˜๋ฉด ์„ธ๋ฒˆ์งธ๋กœ, onClick์„ ํ•˜๋ฉด ๋‘๋ฒˆ์งธ๋กœ, ๋‘๋ฒˆ์งธ์—์„œ ํด๋ฆญํ•˜๋ฉด ์„ธ๋ฒˆ์งธ๋กœ ๊ฐ€๋Š” ํ๋ฆ„์„ ํ•œ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ๋‹ค

 

์œ„์—์„œ ์‚ดํŽด๋ดค์—ˆ๋˜ SKT USIM ์˜จ๋ผ์ธ ์‹ ๊ทœ๊ฐ€์ž…์˜ ์˜ˆ์‹œ๋ฅผ mermaid ๋ฌธ๋ฒ•์œผ๋กœ ๋ฐ”๊พธ๊ณ 

 
  graph TD
       ๊ฐ€์ž…๋ฐฉ์‹[๊ฐ€์ž…๋ฐฉ์‹] -->|on์‹ ๊ทœ๊ฐ€์ž…ํด๋ฆญ| ํ†ต์‹ ์œ ํ˜•[ํ†ต์‹ ์œ ํ˜•]
       ํ†ต์‹ ์œ ํ˜•[ํ†ต์‹ ์œ ํ˜•] -->|5G๋˜๋Š”LTE์„ ํƒ| 5G๋˜๋Š”LTE[5G๋˜๋Š”LTE] -->|on๋‹ค์Œ ํด๋ฆญ| ์š”๊ธˆ์ œ[์š”๊ธˆ์ œ]
       ์š”๊ธˆ์ œ[์š”๊ธˆ์ œ] -->|FLO์•ค๋ฐ์ดํ„ฐ๋ฌด๋ฃŒ ๋˜๋Š” Wavve์•ค๋ฐ์ดํ„ฐํ”„๋ฆฌ๋ฏธ์—„๋ฌด๋ฃŒ ๋˜๋Š” ์šฐ์ฃผํŒจ์Šคall๋ฌด๋ฃŒ ์„ ํƒ| FLO์•ค๋ฐ์ดํ„ฐ๋ฌด๋ฃŒ_๋˜๋Š”_Wavve์•ค๋ฐ์ดํ„ฐํ”„๋ฆฌ๋ฏธ์—„๋ฌด๋ฃŒ_๋˜๋Š”_์šฐ์ฃผํŒจ์Šคall๋ฌด๋ฃŒ[FLO์•ค๋ฐ์ดํ„ฐ๋ฌด๋ฃŒ_๋˜๋Š”_Wavve์•ค๋ฐ์ดํ„ฐํ”„๋ฆฌ๋ฏธ์—„๋ฌด๋ฃŒ_๋˜๋Š”_์šฐ์ฃผํŒจ์Šคall๋ฌด๋ฃŒ] -->|on๋‹ค์Œ ํด๋ฆญ| ์š”๊ธˆํ™•์ธ[์š”๊ธˆํ™•์ธ]
       ์š”๊ธˆํ™•์ธ[์š”๊ธˆํ™•์ธ] --> |on๋‹ค์Œ ํด๋ฆญ| ํ˜œํƒ[ํ˜œํƒ]
       ํ˜œํƒ[ํ˜œํƒ] --> |ํƒ€๋‹คํŒฉ์›์Šคํ† ์–ด ๋˜๋Š” ํƒ€๋‹คํŒฉUT ๋˜๋Š” ํƒ€๋‹คํŒฉ11๋ฒˆ๊ฐ€ ์„ ํƒ| ํƒ€๋‹คํŒฉ์›์Šคํ† ์–ด_๋˜๋Š”_ํƒ€๋‹คํŒฉUT_๋˜๋Š”_ํƒ€๋‹คํŒฉ11๋ฒˆ๊ฐ€_์„ ํƒ[ํƒ€๋‹คํŒฉ์›์Šคํ† ์–ด_๋˜๋Š”_ํƒ€๋‹คํŒฉUT_๋˜๋Š”_ํƒ€๋‹คํŒฉ11๋ฒˆ๊ฐ€_์„ ํƒ]
ํƒ€๋‹คํŒฉ์›์Šคํ† ์–ด_๋˜๋Š”_ํƒ€๋‹คํŒฉUT_๋˜๋Š”_ํƒ€๋‹คํŒฉ11๋ฒˆ๊ฐ€_์„ ํƒ[ํƒ€๋‹คํŒฉ์›์Šคํ† ์–ด_๋˜๋Š”_ํƒ€๋‹คํŒฉUT_๋˜๋Š”_ํƒ€๋‹คํŒฉ11๋ฒˆ๊ฐ€_์„ ํƒ]--> |on๋‹ค์Œ ํด๋ฆญ| ๊ฐœ์ธ์ •๋ณด[๊ฐœ์ธ์ •๋ณด]
       ๊ฐœ์ธ์ •๋ณด[๊ฐœ์ธ์ •๋ณด] --> |on๋ณธ์ธ์ธ์ฆ ์™„๋ฃŒ| ๊ฐ€์ž…์™„๋ฃŒ[๊ฐ€์ž…์™„๋ฃŒ]
 

 

mermaid๋กœ ํ”Œ๋กœ์šฐ ๊ทธ๋ ค๋ณด์ž๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

mermaid๋กœ ๊ทธ๋ฆฐ ํŽ˜์ด์ง€ ํ”Œ๋กœ์šฐ

๋ชจ์•„์„œ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

ํ•œ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ๋Š” ํผ๋„ ํ”Œ๋กœ์šฐ

 

์ฆ‰, ๊ฐ ๋‹จ๊ณ„๋ฅผ ๊ฐ€์ž…๋ฐฉ์‹[๊ฐ€์ž…๋ฐฉ์‹] -->|on์‹ ๊ทœ๊ฐ€์ž…ํด๋ฆญ| ํ†ต์‹ ์œ ํ˜•[ํ†ต์‹ ์œ ํ˜•] ํ˜•ํƒœ๋กœ ํŒŒ์‹ฑ ํ•ด์ฃผ๋ฉด ๋˜๊ณ , ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

  function getGraph(step: string, children: ReactElement[]) {
    const result: string[] = ['graph TD'];
    children.map(stepElement => {
      const stepName = stepElement.props.name;
      const children = stepElement.props.children;
      const childrenProps = children?.props as [string, unknown];
      Object.entries(childrenProps).map(el => {
        const [functionName, value] = el;
        if (typeof value === 'function') {
          value.toString().match(/setStep\(.+\)/g)
            ?.map(matchedSetStep => {
              const matchedStepName = matchedSetStep.match(/setStep\((?:'|")(.+)(?:'|")\)/)?.[1];
              const graphNode =
                `${stepName}[${stepName}] -->|${functionName}| ${matchedStepName}[${matchedStepName}]`;
              result.push(graphNode);
            });
        }
      });
    });
    return result.join('\n');
  }

๐Ÿค” ๋งˆ์น˜๋ฉด์„œ

funnel ํŒจํ„ด์œผ๋กœ ํ•˜๋‚˜์˜ ๊ฑฐ๋Œ€ํ•œ ํŽ˜์ด์ง€์˜ ํผ ํ˜•์‹์„

์ฝ”๋“œ์ ์œผ๋กœ ์‘์ง‘๋„์™€ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ด๊ณ  (use-funnel),  ์‹œ๊ฐํ™” (Funnel Debugger)ํ•˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•ด ์‚ดํŽด๋ดค๋‹ค.

 

์•„์‰ฌ์šด ์ ์€ useFunnel ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉ (์ด ๊ธ€ ์ž‘์„ฑ์ผ ๊ธฐ์ค€ 2024.07.05)์„ ํ•ด๋ณด๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ์–ด๋ ค์›€(?)์ด ์ข€ ์žˆ์—ˆ๋‹ค.

์ผ๋‹จ react(next X)์—์„œ useFunnel์„ ์‚ฌ์šฉํ•ด๋ณด๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ ์ผ๋‹จ next์—์„œ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ๋“ฏํ•˜๋‹ค.

next์—์„œ ์‚ฌ์šฉํ•ด๋ณด๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ next/router๊ฐ€ next14๋ถ€ํ„ฐ๋Š” ๋ณธ๊ฒฉ์ ์œผ๋กœ app ๋ผ์šฐํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ํŒจํ‚ค์ง€๋Š” ์•„์ง 

next12 ๊ธฐ์ค€์ด๋ผ์„œ ๊ทธ๋Ÿฐ์ง€ ๋ฒ„์ „์„ ๋‚ฎ์ถฐ์„œ ์‚ฌ์šฉํ•ด์•ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๋“ฏํ•˜๋‹ค.

์ด ๊ธฐํšŒ์— ๋‚˜๋งŒ์˜ useFunnel์„ ์‹œ๊ฐ„์ด ๋‚˜๋ฉด ์กฐ๊ธˆ์”ฉ ๊ตฌํ˜„ํ•ด ๋ณด๋Š” ๊ฒƒ๋„ ์žฌ๋ฏธ์žˆ์„ ๊ฑฐ ๊ฐ™๋‹ค.

 

์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ„ฐ๋ง ํ•˜๋Š” ๋ฐฉ๋ฒ•, ์ฝ”๋“œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋งŒ๋“œ๋Š” ์‚ฌ๋žŒ๋“ค์˜ ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•๋“ค์— ๋Œ€ํ•ด ์•Œ๊ฒŒ ๋˜์–ด์„œ ์ข‹์•˜๋‹ค. ๐Ÿ€


๐Ÿ“š References

https://www.youtube.com/watch?v=NwLWX2RNVcw

ํ† ์Šค | SLASH 23 = ํผ๋„ : ์Ÿ์•„์ง€๋Š” ํŽ˜์ด์ง€ ํ•œ ๋ฐฉ์— ๊ด€๋ฆฌํ•˜๊ธฐ

https://toss.tech/article/how-platform-designer-make-effectiveness

 

ํ”Œ๋žซํผ ๋””์ž์ด๋„ˆ๊ฐ€ ํšจ์œจ์„ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๋ฒ•

์ˆ˜๋งŽ์€ ๊ฐ€์ง“์ˆ˜๋“ค์„ ๋‹จ์ˆœํžˆ ๋”ํ•˜๊ธฐ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ณฑํ•˜๊ธฐ๋กœ ํ™•์žฅํ•˜๋ฉด์„œ ๊ทน๋‹จ์ ์ธ ํšจ์œจ๊ณผ ์‹ฌ๋ฏธ์„ฑ๊นŒ์ง€ ์ฑ™๊ฒผ๋˜ ๊ณผ์ •๋“ค์„ ํ”Œ๋กœ์šฐ์ฐจํŠธ ์ œ์ž‘ ํ”„๋กœ์ ํŠธ๋ฅผ ์˜ˆ์‹œ๋กœ ์†Œ๊ฐœํ•ด๋“œ๋ฆด๊ฒŒ์š”.

toss.tech

 

https://www.slash.page/libraries/react/use-funnel/readme.i18n/

https://mermaid.js.org/syntax/examples.html#basic-flowchart

 

Examples | Mermaid

 

mermaid.js.org