mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-03-06 17:34:59 +08:00
refactor: simpler way to check canGoBack (#54)
This commit is contained in:
committed by
Michał Osadnik
parent
82b771aa57
commit
4a3db4e6f4
@@ -96,10 +96,6 @@ export default function MockRouter(options: DefaultRouterOptions) {
|
||||
shouldActionChangeFocus() {
|
||||
return false;
|
||||
},
|
||||
|
||||
canGoBack() {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
return router;
|
||||
|
||||
@@ -102,14 +102,68 @@ it("returns correct value for canGoBack when it's not overridden", () => {
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
|
||||
it("returns correct value for canGoBack when it's overridden", () => {
|
||||
it(`returns false for canGoBack when current router doesn't handle GO_BACK`, () => {
|
||||
function TestRouter(options: DefaultRouterOptions) {
|
||||
const CurrentMockRouter = MockRouter(options);
|
||||
const ChildRouter: Router<NavigationState, MockActions> = {
|
||||
...CurrentMockRouter,
|
||||
|
||||
getStateForAction(state, action) {
|
||||
if (action.type === 'GO_BACK') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return CurrentMockRouter.getStateForAction(state, action);
|
||||
},
|
||||
};
|
||||
return ChildRouter;
|
||||
}
|
||||
|
||||
const TestNavigator = (props: any) => {
|
||||
const { state, descriptors } = useNavigationBuilder<
|
||||
NavigationState,
|
||||
any,
|
||||
any
|
||||
>(TestRouter, props);
|
||||
|
||||
return descriptors[state.routes[state.index].key].render();
|
||||
};
|
||||
|
||||
let result = false;
|
||||
|
||||
const TestScreen = ({ navigation }: any): any => {
|
||||
React.useEffect(() => {
|
||||
result = navigation.canGoBack();
|
||||
});
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const root = (
|
||||
<NavigationContainer>
|
||||
<TestNavigator>
|
||||
<Screen name="baz" component={TestScreen} />
|
||||
</TestNavigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
|
||||
render(root).update(root);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true for canGoBack when current router handles GO_BACK', () => {
|
||||
function ParentRouter(options: DefaultRouterOptions) {
|
||||
const CurrentMockRouter = MockRouter(options);
|
||||
const ChildRouter: Router<NavigationState, MockActions> = {
|
||||
...CurrentMockRouter,
|
||||
|
||||
canGoBack() {
|
||||
return true;
|
||||
getStateForAction(state, action) {
|
||||
if (action.type === 'GO_BACK') {
|
||||
return state;
|
||||
}
|
||||
|
||||
return CurrentMockRouter.getStateForAction(state, action);
|
||||
},
|
||||
};
|
||||
return ChildRouter;
|
||||
@@ -160,17 +214,21 @@ it("returns correct value for canGoBack when it's overridden", () => {
|
||||
|
||||
render(root).update(root);
|
||||
|
||||
expect(result).toEqual(true);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('returns correct value for canGoBack when parent router overrides it', () => {
|
||||
it('returns true for canGoBack when parent router handles GO_BACK', () => {
|
||||
function OverrodeRouter(options: DefaultRouterOptions) {
|
||||
const CurrentMockRouter = MockRouter(options);
|
||||
const ChildRouter: Router<NavigationState, MockActions> = {
|
||||
...CurrentMockRouter,
|
||||
|
||||
canGoBack() {
|
||||
return true;
|
||||
getStateForAction(state, action) {
|
||||
if (action.type === 'GO_BACK') {
|
||||
return state;
|
||||
}
|
||||
|
||||
return CurrentMockRouter.getStateForAction(state, action);
|
||||
},
|
||||
};
|
||||
return ChildRouter;
|
||||
@@ -228,7 +286,7 @@ it('returns correct value for canGoBack when parent router overrides it', () =>
|
||||
|
||||
render(root).update(root);
|
||||
|
||||
expect(result).toEqual(false);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('sets options with options prop as a fuction', () => {
|
||||
|
||||
@@ -169,13 +169,6 @@ export type Router<
|
||||
*/
|
||||
shouldActionChangeFocus(action: NavigationAction): boolean;
|
||||
|
||||
/**
|
||||
* Whether the back action will be handled by navigation
|
||||
*
|
||||
* @param state State object to check.
|
||||
*/
|
||||
canGoBack(state: State): boolean;
|
||||
|
||||
/**
|
||||
* Action creators for the router.
|
||||
*/
|
||||
|
||||
@@ -68,7 +68,8 @@ export default function useNavigationHelpers<
|
||||
? parentNavigationHelpers.isFocused
|
||||
: () => true,
|
||||
canGoBack: () =>
|
||||
router.canGoBack(getState()) ||
|
||||
router.getStateForAction(getState(), BaseActions.goBack() as Action) !==
|
||||
null ||
|
||||
(parentNavigationHelpers && parentNavigationHelpers.canGoBack()) ||
|
||||
false,
|
||||
} as NavigationHelpers<ParamListBase> &
|
||||
|
||||
@@ -225,10 +225,6 @@ export default function StackRouter(options: StackRouterOptions) {
|
||||
}
|
||||
},
|
||||
|
||||
canGoBack(state) {
|
||||
return state.routes.length > 1;
|
||||
},
|
||||
|
||||
actionCreators: StackActions,
|
||||
};
|
||||
|
||||
|
||||
@@ -211,10 +211,6 @@ export default function TabRouter({
|
||||
return action.type === 'NAVIGATE';
|
||||
},
|
||||
|
||||
canGoBack(state) {
|
||||
return router.getStateForAction(state, { type: 'GO_BACK' }) !== null;
|
||||
},
|
||||
|
||||
actionCreators: TabActions,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user