Skip to content
Permalink
Browse files

Kill NavigationReducers

Summary:
For navigation actions at high level, reducers from NavigationReducers does not
know anything about the app-specific state thus people won't use these reducers.
Instead, people should build their own reducers.

There are a lot of good libraries available that help people to reducing things if that's
what they really need.

At the low level, for navigation state changes that don't involve app-specific state,
`NavigationStateUtils` should server that kind of need.

`NavigationReducers` serves little benefit cause it does not know the app state, it does
not know how to traverse the navigation states which can be a tree, a list or a map.

That said, we hold no interest in owning in the core navigation library.

Reviewed By: ericvicenti

Differential Revision: D3372910

fbshipit-source-id: 797382b46e7d64b7ad578b51dd37e2b941faa83d
  • Loading branch information
Hedger Wang Facebook Github Bot 4
Hedger Wang authored and Facebook Github Bot 4 committed Jun 8, 2016
1 parent bb9ed2d commit 3a8b50ad550b176bbce5713c5c74e1318c10f2a0
@@ -80,7 +80,7 @@ class YourApplication extends React.Component {
switch (type) {
case 'push':
// push a new route.
const route = {key: Date.now()};
const route = {key: 'route-' + Date.now()};
navigationState = NavigationStateUtils.push(navigationState, route);
break;

@@ -22,27 +22,72 @@
*/
'use strict';

const React = require('react');
const ReactNative = require('react-native');
// $FlowFixMe : This is a platform-forked component, and flow seems to only run on iOS?
const UIExplorerList = require('./UIExplorerList');

const {
NavigationExperimental,
} = ReactNative;


const {
Reducer: NavigationReducer,
StateUtils: NavigationStateUtils,
} = NavigationExperimental;
const StackReducer = NavigationReducer.StackReducer;

import type {NavigationState} from 'NavigationTypeDefinition';

import type {UIExplorerAction} from './UIExplorerActions';

export type UIExplorerNavigationState = {
externalExample: ?string;
stack: NavigationState;
};

const defaultGetReducerForState = (initialState) => (state) => state || initialState;

function StackReducer({initialState, getReducerForState, getPushedReducerForAction}: any): Function {
const getReducerForStateWithDefault = getReducerForState || defaultGetReducerForState;
return function (lastState: ?NavigationState, action: any): NavigationState {
if (!lastState) {
return initialState;
}
const lastParentState = NavigationStateUtils.getParent(lastState);
if (!lastParentState) {
return lastState;
}

const activeSubState = lastParentState.routes[lastParentState.index];
const activeSubReducer = getReducerForStateWithDefault(activeSubState);
const nextActiveState = activeSubReducer(activeSubState, action);
if (nextActiveState !== activeSubState) {
const nextChildren = [...lastParentState.routes];
nextChildren[lastParentState.index] = nextActiveState;
return {
...lastParentState,
routes: nextChildren,
};
}

const subReducerToPush = getPushedReducerForAction(action, lastParentState);
if (subReducerToPush) {
return NavigationStateUtils.push(
lastParentState,
subReducerToPush(null, action)
);
}

switch (action.type) {
case 'back':
case 'BackAction':
if (lastParentState.index === 0 || lastParentState.routes.length === 1) {
return lastParentState;
}
return NavigationStateUtils.pop(lastParentState);
}

return lastParentState;
};
}

const UIExplorerStackReducer = StackReducer({
getPushedReducerForAction: (action, lastState) => {
if (action.type === 'UIExplorerExampleAction' && UIExplorerList.Modules[action.openExample]) {
@@ -106,7 +151,7 @@ function UIExplorerNavigationReducer(lastState: ?UIExplorerNavigationState, acti
return {
externalExample: null,
stack: newStack,
}
};
}
return lastState;
}
@@ -16,14 +16,12 @@ const NavigationCard = require('NavigationCard');
const NavigationCardStack = require('NavigationCardStack');
const NavigationHeader = require('NavigationHeader');
const NavigationPropTypes = require('NavigationPropTypes');
const NavigationReducer = require('NavigationReducer');
const NavigationStateUtils = require('NavigationStateUtils');
const NavigationTransitioner = require('NavigationTransitioner');

const NavigationExperimental = {
// Core
StateUtils: NavigationStateUtils,
Reducer: NavigationReducer,

// Views
AnimatedView: NavigationAnimatedView,

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

3 comments on commit 3a8b50a

@steida

This comment has been minimized.

Copy link

steida replied Jun 9, 2016

💯

@xing-zheng

This comment has been minimized.

Copy link
Contributor

xing-zheng replied Jul 6, 2016

Hi @hedgerwang , I appreciate the NavigationExperimental component very much, Could you tell me we where can I found the latest document about this component, I found the navigation-rfc project is not maintained.

@hedgerwang

This comment has been minimized.

Copy link
Contributor

hedgerwang replied Jul 6, 2016

@xing-zheng : we're working on the documentation and they should be ready in few weeks.

Please sign in to comment.
You can’t perform that action at this time.