Skip to content

Commit c197f73

Browse files
fix(native): overlay close on empty history stack (#79)
* fix(native): add testcase for overlay on empty history stack * fix(native): add unfinished fallback behaviour for overlay error * Update packages/react-navigation-native/src/index.ts Co-authored-by: MinuKang <minukang5874@gmail.com> * Update packages/react-navigation-native/src/index.ts Co-authored-by: MinuKang <minukang5874@gmail.com> --------- Co-authored-by: MinuKang <minukang5874@gmail.com>
1 parent 4726fea commit c197f73

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

packages/react-navigation-native/src/index.ts

+20
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,26 @@ export const useFunnel = createUseFunnel(({ id, initialState }) => {
142142
if (delta === -1) {
143143
if (navigation.canGoBack()) {
144144
navigation.goBack();
145+
} else {
146+
// FIXME: 미완성 코드. 관련 에러: https://github.com/toss/use-funnel/issues/77
147+
// 이렇게 해도 네이티브 뒤로가기 시의 문제는 여전히 해결할 수 없음
148+
if (params && params.index > 0 && navigation.getState().index === 0 && params.isOverlay) {
149+
const prevHistory = (params.histories ?? [])[params.index - 1];
150+
const newState: NativeFunnelState = {
151+
step: prevHistory.step,
152+
context: prevHistory.context,
153+
index: params.index - 1,
154+
histories: (params.histories ?? []).slice(0, params.index),
155+
isOverlay: overlayStepMapRef.current[prevHistory.step],
156+
};
157+
navigation.setParams({
158+
...route.params,
159+
[navigationParamName]: {
160+
...useFunnelState,
161+
[id]: newState,
162+
},
163+
});
164+
}
145165
}
146166
} else {
147167
// find delta index

packages/react-navigation-native/test/index.test.tsx

+62
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,66 @@ describe('Test useFunnel react-navigation-native router', () => {
140140
expect(screen.queryByText('B title : replace-test')).toBeNull();
141141
expect(screen.queryByText('A : Go B')).not.toBeNull();
142142
});
143+
144+
test('The overlay should work even if there is no history', async () => {
145+
function NoHistoryOverlayTest() {
146+
const funnel = useFunnel<{
147+
A: { id?: string };
148+
Overlay: {};
149+
}>({
150+
id: 'first-history-overlay-test',
151+
initial: {
152+
step: 'A',
153+
context: {},
154+
},
155+
});
156+
return (
157+
<funnel.Render
158+
A={({ history }) => (
159+
<View>
160+
<Button title="A : Go Overlay" onPress={() => history.push('Overlay')} />
161+
</View>
162+
)}
163+
Overlay={funnel.Render.overlay({
164+
render({ close }) {
165+
return (
166+
<View>
167+
<Text>Overlay : title</Text>
168+
<Button title="Overlay : Close Overlay" onPress={() => close()} />
169+
</View>
170+
);
171+
},
172+
})}
173+
/>
174+
);
175+
}
176+
177+
const navigationRef = createNavigationContainerRef();
178+
179+
render(
180+
<NavigationContainer ref={navigationRef}>
181+
<Stack.Navigator>
182+
<Stack.Screen name="Home" component={NoHistoryOverlayTest} />
183+
</Stack.Navigator>
184+
</NavigationContainer>,
185+
);
186+
187+
const user = userEvent.setup();
188+
189+
// The first screen is "A"
190+
expect(screen.queryByText('A : Go Overlay')).not.toBeNull();
191+
192+
// When the user presses the "A : Go Overlay" button
193+
await user.press(screen.getByText('A : Go Overlay'));
194+
195+
// The screen should be "Overlay"
196+
expect(screen.queryByText('Overlay : title')).not.toBeNull();
197+
198+
// When the user presses the "Overlay : Close Overlay" button
199+
await user.press(screen.getByText('Overlay : Close Overlay'));
200+
201+
// The screen should be "A", overlay is closed
202+
expect(screen.queryByText('Overlay : title')).toBeNull();
203+
expect(screen.queryByText('A : Go Overlay')).not.toBeNull();
204+
});
143205
});

0 commit comments

Comments
 (0)