Skip to content
This repository has been archived by the owner on Feb 8, 2020. It is now read-only.

Commit

Permalink
feat: add an update action to update routes
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Jul 18, 2019
1 parent 66202e1 commit e577698
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 39 deletions.
31 changes: 31 additions & 0 deletions example/StackNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ const StackRouter: Router<CommonAction | Action> = {
],
};
}

return null;

case 'REPLACE': {
Expand All @@ -192,6 +193,36 @@ const StackRouter: Router<CommonAction | Action> = {
};
}

case 'UPDATE': {
if (
action.payload.name !== undefined &&
!state.routeNames.includes(action.payload.name)
) {
return null;
}

const index =
action.payload.key !== undefined
? state.routes.findIndex(route => route.key === action.payload.key)
: state.index;

if (index === -1) {
return null;
}

return {
...state,
routes: [
...state.routes.slice(0, index),
{
...state.routes[index],
...action.payload,
},
...state.routes.slice(index + 1),
],
};
}

case 'GO_BACK':
return StackRouter.getStateForAction(state, {
type: 'POP',
Expand Down
35 changes: 25 additions & 10 deletions example/TabNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,33 @@ const TabRouter: Router<Action | CommonAction> = {

return null;

case 'REPLACE': {
case 'UPDATE': {
if (
action.payload.name !== undefined &&
!state.routeNames.includes(action.payload.name)
) {
return null;
}

const index =
action.payload.key !== undefined
? state.routes.findIndex(route => route.key === action.payload.key)
: state.index;

if (index === -1) {
return null;
}

return {
...state,
routes: state.routes.map((route, i) =>
i === state.index
? {
key: `${action.payload.name}-${shortid()}`,
name: action.payload.name,
params: action.payload.params,
}
: route
),
routes: [
...state.routes.slice(0, index),
{
...state.routes[index],
...action.payload,
},
...state.routes.slice(index + 1),
],
};
}

Expand Down
2 changes: 1 addition & 1 deletion example/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ function App() {
name="first"
component={First}
options={{ title: 'Foo' }}
defaultParams={{ author: 'Jane' }}
initialParams={{ author: 'Jane' }}
/>
<MyStack.Screen
name="second"
Expand Down
7 changes: 6 additions & 1 deletion src/BaseActions.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PartialState } from './types';
import { PartialState, Route } from './types';

export type Action =
| { type: 'GO_BACK' }
Expand All @@ -10,6 +10,7 @@ export type Action =
type: 'REPLACE';
payload: { name: string; params?: object };
}
| { type: 'UPDATE'; payload: Partial<Route> }
| {
type: 'RESET';
payload: PartialState & { key?: string };
Expand All @@ -27,6 +28,10 @@ export function replace(name: string, params?: object): Action {
return { type: 'REPLACE', payload: { name, params } };
}

export function update(route: Partial<Route>): Action {
return { type: 'UPDATE', payload: route };
}

export function reset(state: PartialState & { key?: string }): Action {
return { type: 'RESET', payload: state };
}
2 changes: 1 addition & 1 deletion src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ it('initializes state for a navigator on navigation', () => {
<Screen
name="foo"
component={FooScreen}
defaultParams={{ count: 10 }}
initialParams={{ count: 10 }}
/>
<Screen name="bar" component={jest.fn()} />
<Screen name="baz">
Expand Down
41 changes: 28 additions & 13 deletions src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,17 @@ export type Router<Action extends NavigationAction = CommonAction> = {
action: Action
): NavigationState | null;

/**
* Update state for a child navigator and focus it
*
* @param state State object to apply the action on.
* @param options.update Updated navigation state for the child navigator.
* @param options.focus Whether to focus the new child.
* @param options.key Route key of the child to update.
*/
getStateForChildUpdate(
state: NavigationState,
payload: {
options: {
update: NavigationState;
focus: boolean;
key: string | undefined;
Expand All @@ -116,21 +124,17 @@ export type Router<Action extends NavigationAction = CommonAction> = {
/**
* Whether the action bubbles to other navigators
* When an action isn't handled by current navigator, it can be passed to nested navigators
*
* @param action Action object to check.
*/
shouldActionPropagateToChildren(
action: NavigationAction,
navigatorKey: string,
sourceNavigatorKey?: string
): boolean;
shouldActionPropagateToChildren(action: NavigationAction): boolean;

/**
* Whether the action should also change focus in parent navigator
*
* @param action Action object to check.
*/
shouldActionChangeFocus(
action: NavigationAction,
navigatorKey: string,
sourceNavigatorKey?: string
): boolean;
shouldActionChangeFocus(action: NavigationAction): boolean;

/**
* Action creators for the router.
Expand Down Expand Up @@ -186,6 +190,17 @@ export type NavigationHelpers<
: [RouteName, ParamList[RouteName]]
): void;

/**
* Update properties for a route, for example: updating params.
* If a key is provided, the route with matching key will be updated.
* If no key is provided, the focused route will be updated.
*
* @param route New properties for the route object.
*/
update<RouteName extends keyof ParamList>(
route: Partial<RouteProp<ParamList, RouteName>>
): void;

/**
* Reset the navigation state to the provided state.
* If a key is provided, the state with matching key will be reset.
Expand Down Expand Up @@ -258,9 +273,9 @@ export type RouteConfig<
options?: Options;

/**
* Default params object for the route.
* Initial params object for the route.
*/
defaultParams?: ParamList[RouteName];
initialParams?: ParamList[RouteName];
} & (
| {
/**
Expand Down
2 changes: 1 addition & 1 deletion src/useNavigationBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default function useNavigationBuilder(
: routeNames[0];
const initialParamsList = routeNames.reduce(
(acc, curr) => {
acc[curr] = screens[curr].defaultParams;
acc[curr] = screens[curr].initialParams;
return acc;
},
{} as { [key: string]: object | undefined }
Expand Down
14 changes: 2 additions & 12 deletions src/useOnAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@ export default function useOnAction({

if (result !== null) {
if (handleChildUpdateParent) {
const shouldFocus = router.shouldActionChangeFocus(
action,
state.key,
sourceNavigatorKey
);
const shouldFocus = router.shouldActionChangeFocus(action);

handleChildUpdateParent(result, shouldFocus, key);
} else if (state !== result) {
Expand All @@ -62,13 +58,7 @@ export default function useOnAction({
}
}

if (
router.shouldActionPropagateToChildren(
action,
state.key,
sourceNavigatorKey
)
) {
if (router.shouldActionPropagateToChildren(action)) {
for (let i = actionListeners.length - 1; i >= 0; i--) {
const listener = actionListeners[i];

Expand Down

0 comments on commit e577698

Please sign in to comment.