mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-05-01 21:54:51 +08:00
refactor: discard all routes but last when getting action from state
This commit is contained in:
@@ -124,7 +124,8 @@ export default function App() {
|
||||
prefixes: LinkingPrefixes,
|
||||
config: {
|
||||
Root: {
|
||||
path: 'root',
|
||||
path: '',
|
||||
initialRouteName: 'Home',
|
||||
screens: Object.keys(SCREENS).reduce<{ [key: string]: string }>(
|
||||
(acc, name) => {
|
||||
// Convert screen names such as SimpleStack to kebab case (simple-stack)
|
||||
@@ -135,7 +136,7 @@ export default function App() {
|
||||
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
{ Home: '' }
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -41,10 +41,9 @@ it('gets navigate action from state', () => {
|
||||
},
|
||||
type: 'NAVIGATE',
|
||||
});
|
||||
});
|
||||
|
||||
it('gets reset action from state', () => {
|
||||
const state = {
|
||||
expect(
|
||||
getActionFromState({
|
||||
routes: [
|
||||
{
|
||||
name: 'foo',
|
||||
@@ -66,10 +65,40 @@ it('gets reset action from state', () => {
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(getActionFromState(state)).toEqual({
|
||||
payload: state,
|
||||
type: 'RESET_ROOT',
|
||||
})
|
||||
).toEqual({
|
||||
payload: {
|
||||
name: 'foo',
|
||||
params: {
|
||||
screen: 'bar',
|
||||
params: {
|
||||
screen: 'quz',
|
||||
},
|
||||
},
|
||||
},
|
||||
type: 'NAVIGATE',
|
||||
});
|
||||
});
|
||||
|
||||
it('gets reset action from state', () => {
|
||||
const state = {
|
||||
routes: [
|
||||
{
|
||||
name: 'foo',
|
||||
state: {
|
||||
routes: [
|
||||
{
|
||||
name: 'bar',
|
||||
state: {
|
||||
routes: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(getActionFromState(state)).toBe(undefined);
|
||||
expect(getActionFromState({ routes: [] })).toBe(undefined);
|
||||
});
|
||||
|
||||
@@ -5,37 +5,36 @@ type NavigateParams = {
|
||||
params?: NavigateParams;
|
||||
};
|
||||
|
||||
type Action =
|
||||
| {
|
||||
type NavigateAction = {
|
||||
type: 'NAVIGATE';
|
||||
payload: { name: string; params: NavigateParams };
|
||||
}
|
||||
| {
|
||||
type: 'RESET_ROOT';
|
||||
payload: PartialState<NavigationState>;
|
||||
};
|
||||
};
|
||||
|
||||
export default function getActionFromState(
|
||||
state: PartialState<NavigationState>
|
||||
): Action {
|
||||
let payload: { name: string; params: NavigateParams } | undefined;
|
||||
): NavigateAction | undefined {
|
||||
if (state.routes.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (state.routes.length === 1) {
|
||||
// Try to construct payload for a `NAVIGATE` action from the state
|
||||
// This lets us preserve the navigation state and not lose it
|
||||
let route = state.routes[0];
|
||||
let route = state.routes[state.routes.length - 1];
|
||||
|
||||
payload = {
|
||||
let payload: { name: string; params: NavigateParams } = {
|
||||
name: route.name,
|
||||
params: { ...route.params },
|
||||
};
|
||||
|
||||
let current = state.routes[0].state;
|
||||
let current = route.state;
|
||||
let params = payload.params;
|
||||
|
||||
while (current) {
|
||||
if (current.routes.length === 1) {
|
||||
route = current.routes[0];
|
||||
if (current.routes.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
route = current.routes[current.routes.length - 1];
|
||||
params.screen = route.name;
|
||||
|
||||
if (route.state) {
|
||||
@@ -46,22 +45,10 @@ export default function getActionFromState(
|
||||
}
|
||||
|
||||
current = route.state;
|
||||
} else {
|
||||
payload = undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (payload) {
|
||||
return {
|
||||
type: 'NAVIGATE',
|
||||
payload,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'RESET_ROOT',
|
||||
payload: state,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -76,10 +76,10 @@ export default function useLinking(
|
||||
if (state) {
|
||||
const action = getActionFromState(state);
|
||||
|
||||
if (action.type === 'RESET_ROOT') {
|
||||
navigation.resetRoot(action.payload);
|
||||
} else {
|
||||
if (action !== undefined) {
|
||||
navigation.dispatch(action);
|
||||
} else {
|
||||
navigation.resetRoot(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,10 +162,10 @@ export default function useLinking(
|
||||
|
||||
pendingStateUpdateRef.current = true;
|
||||
|
||||
if (action.type === 'RESET_ROOT') {
|
||||
navigation.resetRoot(action.payload);
|
||||
} else {
|
||||
if (action !== undefined) {
|
||||
navigation.dispatch(action);
|
||||
} else {
|
||||
navigation.resetRoot(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user