mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-09 09:13:32 +08:00
Support multiple actions in one tick and fire them in the order that they arrive
This commit is contained in:
@@ -24,7 +24,6 @@ class Home extends React.Component {
|
||||
_renderItem = ({ item }) => (
|
||||
<List.Item
|
||||
title={item.title}
|
||||
style={{ backgroundColor: '#fff' }}
|
||||
onPress={() => this.props.navigation.navigate(item.routeName)}
|
||||
/>
|
||||
);
|
||||
@@ -37,6 +36,7 @@ class Home extends React.Component {
|
||||
ItemSeparatorComponent={Divider}
|
||||
renderItem={this._renderItem}
|
||||
keyExtractor={this._keyExtractor}
|
||||
style={{ backgroundColor: '#fff' }}
|
||||
data={data}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -15,12 +15,26 @@ const MyNavScreen = ({ navigation, banner }) => (
|
||||
</View>
|
||||
<Button onPress={() => navigation.openDrawer()} title="Open drawer" />
|
||||
<Button onPress={() => navigation.toggleDrawer()} title="Toggle drawer" />
|
||||
<Button
|
||||
onPress={() => {
|
||||
navigation.openDrawer();
|
||||
navigation.closeDrawer();
|
||||
}}
|
||||
title="Open and immediately close"
|
||||
/>
|
||||
<Button
|
||||
onPress={() => {
|
||||
navigation.closeDrawer();
|
||||
navigation.openDrawer();
|
||||
}}
|
||||
title="Close and immediately open"
|
||||
/>
|
||||
<Button
|
||||
onPress={() => {
|
||||
navigation.openDrawer();
|
||||
setTimeout(() => {
|
||||
navigation.closeDrawer();
|
||||
}, 500);
|
||||
}, 150);
|
||||
}}
|
||||
title="Open then close drawer shortly after"
|
||||
/>
|
||||
|
||||
@@ -24,6 +24,12 @@ export default (routeConfigs, config = {}) => {
|
||||
|
||||
const switchRouter = SwitchRouter(routeConfigs, config);
|
||||
|
||||
let __id = -1;
|
||||
const genId = () => {
|
||||
__id++;
|
||||
return __id;
|
||||
};
|
||||
|
||||
return {
|
||||
...switchRouter,
|
||||
|
||||
@@ -42,9 +48,9 @@ export default (routeConfigs, config = {}) => {
|
||||
return {
|
||||
...switchRouter.getStateForAction(action, undefined),
|
||||
isDrawerOpen: false,
|
||||
openId: 0,
|
||||
closeId: 0,
|
||||
toggleId: 0,
|
||||
openId: genId(),
|
||||
closeId: genId(),
|
||||
toggleId: genId(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -70,28 +76,28 @@ export default (routeConfigs, config = {}) => {
|
||||
if (action.type === DrawerActions.CLOSE_DRAWER) {
|
||||
return {
|
||||
...state,
|
||||
closeId: state.closeId + 1,
|
||||
closeId: genId(),
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === NavigationActions.BACK && state.isDrawerOpen) {
|
||||
return {
|
||||
...state,
|
||||
closeId: state.closeId + 1,
|
||||
closeId: genId(),
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === DrawerActions.OPEN_DRAWER) {
|
||||
return {
|
||||
...state,
|
||||
openId: state.openId + 1,
|
||||
openId: genId(),
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === DrawerActions.TOGGLE_DRAWER) {
|
||||
return {
|
||||
...state,
|
||||
toggleId: state.toggleId + 1,
|
||||
toggleId: genId(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -110,7 +116,7 @@ export default (routeConfigs, config = {}) => {
|
||||
// If any navigation has happened, make sure to close the drawer
|
||||
return {
|
||||
...switchedState,
|
||||
closeId: state.closeId + 1,
|
||||
closeId: genId(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ describe('DrawerRouter', () => {
|
||||
],
|
||||
isDrawerOpen: false,
|
||||
openId: 0,
|
||||
closeId: 0,
|
||||
toggleId: 0,
|
||||
closeId: 1,
|
||||
toggleId: 2,
|
||||
};
|
||||
expect(state).toEqual(expectedState);
|
||||
const state2 = router.getStateForAction(
|
||||
@@ -43,8 +43,8 @@ describe('DrawerRouter', () => {
|
||||
],
|
||||
isDrawerOpen: false,
|
||||
openId: 0,
|
||||
closeId: 1,
|
||||
toggleId: 0,
|
||||
closeId: 3,
|
||||
toggleId: 2,
|
||||
};
|
||||
expect(state2).toEqual(expectedState2);
|
||||
expect(router.getComponentForState(expectedState)).toEqual(ScreenA);
|
||||
@@ -74,8 +74,8 @@ describe('DrawerRouter', () => {
|
||||
isDrawerOpen: false,
|
||||
isTransitioning: false,
|
||||
openId: 0,
|
||||
closeId: 0,
|
||||
toggleId: 0,
|
||||
closeId: 1,
|
||||
toggleId: 2,
|
||||
routes: [
|
||||
{
|
||||
key: 'Foo',
|
||||
@@ -99,22 +99,22 @@ describe('DrawerRouter', () => {
|
||||
Bar: { screen: ScreenB },
|
||||
});
|
||||
const state = router.getStateForAction(INIT_ACTION);
|
||||
expect(state.toggleId).toEqual(0);
|
||||
expect(state.toggleId).toEqual(2);
|
||||
const state2 = router.getStateForAction(
|
||||
{ type: DrawerActions.OPEN_DRAWER },
|
||||
state
|
||||
);
|
||||
expect(state2.openId).toEqual(1);
|
||||
expect(state2.openId).toEqual(3);
|
||||
const state3 = router.getStateForAction(
|
||||
{ type: DrawerActions.CLOSE_DRAWER },
|
||||
state2
|
||||
);
|
||||
expect(state3.closeId).toEqual(1);
|
||||
expect(state3.closeId).toEqual(4);
|
||||
const state4 = router.getStateForAction(
|
||||
{ type: DrawerActions.TOGGLE_DRAWER },
|
||||
state3
|
||||
);
|
||||
expect(state4.toggleId).toEqual(1);
|
||||
expect(state4.toggleId).toEqual(5);
|
||||
});
|
||||
|
||||
test('Drawer opens closes with key targeted', () => {
|
||||
@@ -134,7 +134,7 @@ describe('DrawerRouter', () => {
|
||||
{ type: DrawerActions.OPEN_DRAWER, key: state.key },
|
||||
state2
|
||||
);
|
||||
expect(state3.openId).toEqual(1);
|
||||
expect(state3.openId).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -171,10 +171,10 @@ test('Drawer does not fire close when child routers return new state', () => {
|
||||
});
|
||||
|
||||
const state = router.getStateForAction(INIT_ACTION);
|
||||
expect(state.closeId).toEqual(0);
|
||||
expect(state.closeId).toEqual(1);
|
||||
|
||||
const state2 = router.getStateForAction({ type: 'CHILD_ACTION' }, state2);
|
||||
expect(state2.closeId).toEqual(0);
|
||||
const state2 = router.getStateForAction({ type: 'CHILD_ACTION' }, state);
|
||||
expect(state2.closeId).toEqual(1);
|
||||
expect(state2.routes[0].changed).toEqual(true);
|
||||
});
|
||||
|
||||
@@ -204,13 +204,13 @@ test('DrawerRouter will close drawer on child navigaton, not on child param chan
|
||||
DrawerActions.openDrawer(),
|
||||
emptyState
|
||||
);
|
||||
expect(initState.openId).toBe(1);
|
||||
expect(initState.openId).toBe(3);
|
||||
|
||||
const state0 = router.getStateForAction(
|
||||
NavigationActions.navigate({ routeName: 'Quo' }),
|
||||
initState
|
||||
);
|
||||
expect(state0.closeId).toBe(1);
|
||||
expect(state0.closeId).toBe(4);
|
||||
|
||||
const initSwitchState = initState.routes[initState.index];
|
||||
const initQuxState = initSwitchState.routes[initSwitchState.index];
|
||||
@@ -224,7 +224,7 @@ test('DrawerRouter will close drawer on child navigaton, not on child param chan
|
||||
);
|
||||
const state1switchState = state1.routes[state1.index];
|
||||
const state1quxState = state1switchState.routes[state1switchState.index];
|
||||
expect(state1.closeId).toBe(0); // don't fire close
|
||||
expect(state1.closeId).toBe(1); // don't fire close
|
||||
expect(state1quxState.params.foo).toEqual('bar');
|
||||
});
|
||||
|
||||
@@ -253,10 +253,9 @@ test('goBack closes drawer when inside of stack', () => {
|
||||
);
|
||||
expect(state3.index).toEqual(1);
|
||||
expect(state3.routes[1].isDrawerOpen).toEqual(true);
|
||||
expect(state3.routes[1].closeId).toEqual(0);
|
||||
expect(state3.routes[1].closeId).toEqual(1); // changed
|
||||
const state4 = router.getStateForAction(NavigationActions.back(), state3);
|
||||
expect(state4.index).toEqual(1);
|
||||
expect(state4.routes[1].closeId).toEqual(1);
|
||||
expect(state4.routes[1].closeId).toEqual(4);
|
||||
const state5 = router.getStateForAction(
|
||||
{ type: DrawerActions.DRAWER_CLOSED },
|
||||
state4
|
||||
|
||||
@@ -33,17 +33,24 @@ export default class DrawerView extends React.PureComponent {
|
||||
toggleId: prevToggleId,
|
||||
} = prevProps.navigation.state;
|
||||
|
||||
if (openId !== prevOpenId) {
|
||||
this._drawer.openDrawer();
|
||||
} else if (closeId !== prevCloseId) {
|
||||
this._drawer.closeDrawer();
|
||||
} else if (toggleId !== prevToggleId) {
|
||||
if (isDrawerOpen) {
|
||||
this._drawer.closeDrawer();
|
||||
} else {
|
||||
let prevIds = [prevOpenId, prevCloseId, prevToggleId];
|
||||
let changedIds = [openId, closeId, toggleId]
|
||||
.filter(id => !prevIds.includes(id))
|
||||
.sort((a, b) => a > b);
|
||||
|
||||
changedIds.forEach(id => {
|
||||
if (id === openId) {
|
||||
this._drawer.openDrawer();
|
||||
} else if (id === closeId) {
|
||||
this._drawer.closeDrawer();
|
||||
} else if (id === toggleId) {
|
||||
if (isDrawerOpen) {
|
||||
this._drawer.closeDrawer();
|
||||
} else {
|
||||
this._drawer.openDrawer();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
||||
Reference in New Issue
Block a user