Migrating from @toss/use-funnel
This document explains how to migrate code from @toss/use-funnel (opens in a new tab) to the new @use-funnel
. Since @toss/use-funnel
was written for Next.js Page Router, this document focuses on migrating to @use-funnel/next
.
New Benefits
- Fixed issues where state did not follow history (related document (opens in a new tab))
- Allows defining state for each step
- Supports not only Next.js but also
react-router
and@react-navigation/native
Installation
See Installation (opens in a new tab) for more details.
npm install @use-funnel/next --save
Breaking Changes
Migrating Steps
The new @use-funnel
allows defining not just the steps but also the state for each step. If your funnel in @toss/use-funnel
does not require different states for each step, you can use createFunnelSteps()
provided by @use-funnel
.
Before
import { useFunnel } from '@toss/use-funnel';
const FUNNEL_STEPS = ['A', 'B', 'C'] as const;
const [Funnel, setFunnel] = useFunnel(FUNNEL_STEPS);
After
import { createFunnelSteps } from '@use-funnel/next';
const steps = createFunnelSteps()
.extends(['A', 'B', 'C'])
.build();
const funnel = useFunnel({
steps,
initial: {
step: 'A',
context: {}
}
});
Migrating <Funnel />
, <Funnel.Step />
Components
In @use-funnel
, you no longer need separate components to infer state types for each step. Instead, you can use funnel.step
and funnel.context
returned by useFunnel()
and render based on switch-case
statements.
Before
import { useFunnel } from '@toss/use-funnel';
const [Funnel, setFunnel] = useFunnel([
'A', 'B'
] as const);
return (
<Funnel>
<Funnel.Step name="A">
<div>A</div>
</Funnel.Step>
<Funnel.Step name="B">
<div>B</div>
</Funnel.Step>
</Funnel>
)
After
import {useFunnel} from '@use-funnel/next';
const steps = createFunnelSteps().extends(['A', 'B']).build();
const funnel = useFunnel({
steps,
initial: {
step: 'A',
context: {}
}
});
switch (funnel.step) {
case 'A':
return <div>A</div>;
case 'B':
return <div>B</div>;
}
Alternatively, you can use <funnel.Render />
for a more declarative approach. See the funnel.Render component for more details.
Migrating withState()
If you were using withState()
in @toss/use-funnel
, you can now achieve the same functionality by passing a generic to createFunnelSteps()
.
Before
import { useFunnel } from '@toss/use-funnel';
const [Funnel, state, setState] = useFunnel([
'A', 'B', 'C'
] as const).withState<{
foo?: string;
bar?: number;
}>({
foo: 'Hello',
bar: 5
});
After
import { useFunnel, createFunnelSteps } from '@use-funnel/next';
const steps = createFunnelSteps<{
foo?: string;
bar?: number;
}>()
.extends(['A', 'B', 'C'])
.build();
const funnel = useFunnel({
steps,
initial: {
step: 'A',
context: {
foo: 'Hello',
bar: 5,
},
},
});