mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-06 22:44:22 +08:00
Add sub-reducer support to NavigationStackReducer
Summary: Revise APIs of reducers, and ensure the stack reducer can support sub-reducers Reviewed By: javache Differential Revision: D2959915 fb-gh-sync-id: 20b28b9ead7ace3373489a806486999048d32aef shipit-source-id: 20b28b9ead7ace3373489a806486999048d32aef
This commit is contained in:
committed by
facebook-github-bot-6
parent
876ecb291f
commit
dcb68db758
@@ -29,11 +29,20 @@ var {
|
||||
} = NavigationExperimental;
|
||||
|
||||
const NavigationBasicReducer = NavigationReducer.StackReducer({
|
||||
initialStates: [
|
||||
{key: 'First Route'}
|
||||
],
|
||||
matchAction: action => action.type === 'push',
|
||||
actionStateMap: action => ({key: action.key}),
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (action.type === 'push') {
|
||||
return (state) => state || {key: action.key};
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getReducerForState: (initialState) => (state) => state || initialState,
|
||||
initialState: {
|
||||
key: 'AnimatedExampleStackKey',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'First Route'},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
class NavigationAnimatedExample extends React.Component {
|
||||
|
||||
@@ -26,12 +26,21 @@ const {
|
||||
} = NavigationExperimental;
|
||||
const StackReducer = NavigationReducer.StackReducer;
|
||||
|
||||
const NavigationBasicReducer = StackReducer({
|
||||
initialStates: [
|
||||
{key: 'first_page'}
|
||||
],
|
||||
matchAction: action => true,
|
||||
actionStateMap: action => ({key: action}),
|
||||
const NavigationBasicReducer = NavigationReducer.StackReducer({
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (action.type === 'push') {
|
||||
return (state) => state || {key: action.key};
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getReducerForState: (initialState) => (state) => state || initialState,
|
||||
initialState: {
|
||||
key: 'BasicExampleStackKey',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'First Route'},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const NavigationBasicExample = React.createClass({
|
||||
@@ -51,13 +60,13 @@ const NavigationBasicExample = React.createClass({
|
||||
<NavigationExampleRow
|
||||
text={`Push page #${navState.children.length}`}
|
||||
onPress={() => {
|
||||
onNavigate('page #' + navState.children.length);
|
||||
onNavigate({ type: 'push', key: 'page #' + navState.children.length });
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="pop"
|
||||
onPress={() => {
|
||||
onNavigate(StackReducer.PopAction());
|
||||
onNavigate(NavigationRootContainer.getBackAction());
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
@@ -32,6 +34,8 @@ const {
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const NavigationExampleTabBar = require('./NavigationExampleTabBar');
|
||||
|
||||
import type {NavigationParentState} from 'NavigationStateUtils';
|
||||
|
||||
const ExampleExitAction = () => ({
|
||||
isExitAction: true,
|
||||
});
|
||||
@@ -39,25 +43,25 @@ ExampleExitAction.match = (action) => (
|
||||
action && action.isExitAction === true
|
||||
);
|
||||
|
||||
const ExamplePageAction = (type) => ({
|
||||
const PageAction = (type) => ({
|
||||
type,
|
||||
isPageAction: true,
|
||||
});
|
||||
ExamplePageAction.match = (action) => (
|
||||
PageAction.match = (action) => (
|
||||
action && action.isPageAction === true
|
||||
);
|
||||
|
||||
const ExampleSettingsPageAction = (type) => ({
|
||||
...ExamplePageAction(type),
|
||||
isSettingsPageAction: true,
|
||||
const ExampleProfilePageAction = (type) => ({
|
||||
...PageAction(type),
|
||||
isProfilePageAction: true,
|
||||
});
|
||||
ExampleSettingsPageAction.match = (action) => (
|
||||
action && action.isSettingsPageAction === true
|
||||
ExampleProfilePageAction.match = (action) => (
|
||||
action && action.isProfilePageAction === true
|
||||
);
|
||||
|
||||
const ExampleInfoAction = () => ExamplePageAction('InfoPage');
|
||||
const ExampleInfoAction = () => PageAction('InfoPage');
|
||||
|
||||
const ExampleNotifSettingsAction = () => ExampleSettingsPageAction('NotifSettingsPage');
|
||||
const ExampleNotifProfileAction = () => ExampleProfilePageAction('NotifProfilePage');
|
||||
|
||||
const _jsInstanceUniqueId = '' + Date.now();
|
||||
let _uniqueIdCount = 0;
|
||||
@@ -68,70 +72,70 @@ function pageStateActionMap(action) {
|
||||
};
|
||||
}
|
||||
|
||||
function getTabActionMatcher(key) {
|
||||
return function (action) {
|
||||
if (!ExamplePageAction.match(action)) {
|
||||
return false;
|
||||
}
|
||||
if (ExampleSettingsPageAction.match(action)) {
|
||||
return key === 'settings';
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
var ExampleTabs = [
|
||||
{
|
||||
label: 'Account',
|
||||
reducer: NavigationReducer.StackReducer({
|
||||
initialStates: [
|
||||
{type: 'AccountPage', key: 'base'}
|
||||
],
|
||||
key: 'account',
|
||||
matchAction: getTabActionMatcher('account'),
|
||||
actionStateMap: pageStateActionMap,
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Notifications',
|
||||
reducer: NavigationReducer.StackReducer({
|
||||
initialStates: [
|
||||
{type: 'NotifsPage', key: 'base'}
|
||||
],
|
||||
key: 'notifs',
|
||||
matchAction: getTabActionMatcher('notifs'),
|
||||
actionStateMap: pageStateActionMap,
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Settings',
|
||||
reducer: NavigationReducer.StackReducer({
|
||||
initialStates: [
|
||||
{type: 'SettingsPage', key: 'base'}
|
||||
],
|
||||
key: 'settings',
|
||||
matchAction: getTabActionMatcher('settings'),
|
||||
actionStateMap: pageStateActionMap,
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
const ExampleAppReducer = NavigationReducer.TabsReducer({
|
||||
tabReducers: ExampleTabs.map(tab => tab.reducer),
|
||||
key: 'AppNavigationState',
|
||||
initialIndex: 0,
|
||||
tabReducers: [
|
||||
NavigationReducer.StackReducer({
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (PageAction.match(action) && !ExampleProfilePageAction.match(action)) {
|
||||
return (state) => (state || pageStateActionMap(action));
|
||||
}
|
||||
return null;
|
||||
},
|
||||
initialState: {
|
||||
key: 'notifs',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'base', type: 'NotifsPage'},
|
||||
],
|
||||
},
|
||||
}),
|
||||
NavigationReducer.StackReducer({
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (PageAction.match(action) && !ExampleProfilePageAction.match(action)) {
|
||||
return (state) => (state || pageStateActionMap(action));
|
||||
}
|
||||
return null;
|
||||
},
|
||||
initialState: {
|
||||
key: 'settings',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'base', type: 'SettingsPage'},
|
||||
],
|
||||
},
|
||||
}),
|
||||
NavigationReducer.StackReducer({
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (PageAction.match(action) || ExampleProfilePageAction.match(action)) {
|
||||
return (state) => (state || pageStateActionMap(action));
|
||||
}
|
||||
return null;
|
||||
},
|
||||
initialState: {
|
||||
key: 'profile',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'base', type: 'ProfilePage'},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
function stateTypeTitleMap(pageState) {
|
||||
switch (pageState.type) {
|
||||
case 'AccountPage':
|
||||
return 'Account Page';
|
||||
case 'ProfilePage':
|
||||
return 'Profile Page';
|
||||
case 'NotifsPage':
|
||||
return 'Notifications';
|
||||
case 'SettingsPage':
|
||||
return 'Settings';
|
||||
case 'InfoPage':
|
||||
return 'Info Page';
|
||||
case 'NotifSettingsPage':
|
||||
return 'Notification Settings';
|
||||
case 'NotifProfilePage':
|
||||
return 'Page in Profile';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,9 +177,9 @@ class ExampleTabScreen extends React.Component {
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Open notifs settings in settings tab"
|
||||
text="Open a page in the profile tab"
|
||||
onPress={() => {
|
||||
this.props.onNavigate(ExampleNotifSettingsAction());
|
||||
this.props.onNavigate(ExampleNotifProfileAction());
|
||||
}}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
@@ -196,19 +200,19 @@ class NavigationCompositionExample extends React.Component {
|
||||
return (
|
||||
<NavigationRootContainer
|
||||
reducer={ExampleAppReducer}
|
||||
persistenceKey="NavigationCompositionExampleState"
|
||||
persistenceKey="NavigationCompositionState"
|
||||
ref={navRootContainer => { this.navRootContainer = navRootContainer; }}
|
||||
renderNavigation={this.renderApp.bind(this)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
handleBackAction() {
|
||||
handleBackAction(): boolean {
|
||||
return (
|
||||
this.navRootContainer &&
|
||||
this.navRootContainer.handleNavigation(NavigationRootContainer.getBackAction())
|
||||
);
|
||||
}
|
||||
renderApp(navigationState, onNavigate) {
|
||||
renderApp(navigationState: NavigationParentState, onNavigate: Function) {
|
||||
if (!navigationState) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -36,13 +36,20 @@ export type UIExplorerNavigationState = {
|
||||
};
|
||||
|
||||
const UIExplorerStackReducer = StackReducer({
|
||||
key: 'UIExplorerMainStack',
|
||||
initialStates: [
|
||||
{key: 'AppList'},
|
||||
],
|
||||
initialIndex: 0,
|
||||
matchAction: action => action.openExample && !!UIExplorerList.Modules[action.openExample],
|
||||
actionStateMap: action => ({ key: action.openExample, }),
|
||||
getPushedReducerForAction: (action) => {
|
||||
if (action.type === 'UIExplorerExampleAction' && UIExplorerList.Modules[action.openExample]) {
|
||||
return (state) => state || {key: action.openExample};
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getReducerForState: (initialState) => (state) => state || initialState,
|
||||
initialState: {
|
||||
key: 'UIExplorerMainStack',
|
||||
index: 0,
|
||||
children: [
|
||||
{key: 'AppList'},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
function UIExplorerNavigationReducer(lastState: ?UIExplorerNavigationState, action: any): UIExplorerNavigationState {
|
||||
@@ -86,7 +93,7 @@ function UIExplorerNavigationReducer(lastState: ?UIExplorerNavigationState, acti
|
||||
if (newStack !== lastState.stack) {
|
||||
return {
|
||||
externalExample: null,
|
||||
stack: UIExplorerStackReducer(null, action),
|
||||
stack: newStack,
|
||||
}
|
||||
}
|
||||
return lastState;
|
||||
|
||||
Reference in New Issue
Block a user