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

Commit

Permalink
feat: add a method to reset root navigator state
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Sep 26, 2019
1 parent 8b78d61 commit e61f594
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 22 deletions.
52 changes: 30 additions & 22 deletions packages/core/src/NavigationContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import * as CommonActions from './CommonActions';
import EnsureSingleNavigator from './EnsureSingleNavigator';
import NavigationBuilderContext from './NavigationBuilderContext';
import ResetRootContext from './ResetRootContext';
import useFocusedListeners from './useFocusedListeners';
import useDevTools from './useDevTools';

Expand Down Expand Up @@ -86,6 +87,23 @@ const Container = React.forwardRef(function NavigationContainer(
getPartialState(initialState)
);

const navigationStateRef = React.useRef<State>();
const transactionStateRef = React.useRef<State | null>(null);
const isTransactionActiveRef = React.useRef<boolean>(false);
const isFirstMountRef = React.useRef<boolean>(true);
const skipTrackingRef = React.useRef<boolean>(false);

const reset = React.useCallback((state: NavigationState) => {
skipTrackingRef.current = true;
setNavigationState(state);
}, []);

const { trackState, trackAction } = useDevTools({
name: '@react-navigation',
reset,
state,
});

const { listeners, addListener: addFocusedListener } = useFocusedListeners();

const dispatch = (
Expand All @@ -106,6 +124,14 @@ const Container = React.forwardRef(function NavigationContainer(
}
};

const resetRoot = React.useCallback(
(state: PartialState<NavigationState> | NavigationState) => {
trackAction('@@RESET_ROOT');
setNavigationState(state);
},
[trackAction]
);

React.useImperativeHandle(ref, () => ({
...(Object.keys(CommonActions) as Array<keyof typeof CommonActions>).reduce<
any
Expand All @@ -120,31 +146,11 @@ const Container = React.forwardRef(function NavigationContainer(
);
return acc;
}, {}),
resetRoot: (state: PartialState<NavigationState> | NavigationState) => {
trackAction('@@RESET_ROOT');
setNavigationState(state);
},
resetRoot,
dispatch,
canGoBack,
}));

const navigationStateRef = React.useRef<State>();
const transactionStateRef = React.useRef<State | null>(null);
const isTransactionActiveRef = React.useRef<boolean>(false);
const isFirstMountRef = React.useRef<boolean>(true);
const skipTrackingRef = React.useRef<boolean>(false);

const reset = React.useCallback((state: NavigationState) => {
skipTrackingRef.current = true;
setNavigationState(state);
}, []);

const { trackState, trackAction } = useDevTools({
name: '@react-navigation',
reset,
state,
});

const builderContext = React.useMemo(
() => ({
addFocusedListener,
Expand Down Expand Up @@ -220,7 +226,9 @@ const Container = React.forwardRef(function NavigationContainer(
return (
<NavigationBuilderContext.Provider value={builderContext}>
<NavigationStateContext.Provider value={context}>
<EnsureSingleNavigator>{children}</EnsureSingleNavigator>
<ResetRootContext.Provider value={resetRoot}>
<EnsureSingleNavigator>{children}</EnsureSingleNavigator>
</ResetRootContext.Provider>
</NavigationStateContext.Provider>
</NavigationBuilderContext.Provider>
);
Expand Down
15 changes: 15 additions & 0 deletions packages/core/src/ResetRootContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react';
import { NavigationState, PartialState } from './types';

/**
* Context which holds the method to reset root navigator state.
*/
const ResetRootContext = React.createContext<
(state: PartialState<NavigationState> | NavigationState) => void
>(() => {
throw new Error(
"We couldn't find a way to reset root state. Have you wrapped your app with 'NavigationContainer'?"
);
});

export default ResetRootContext;
7 changes: 7 additions & 0 deletions packages/core/src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,13 @@ type NavigationHelpersCommon<
*/
reset(state: PartialState<State> | State): void;

/**
* Reset the navigation state of the root navigator to the provided state.
*
* @param state Navigation state object.
*/
resetRoot(state: PartialState<NavigationState> | NavigationState): void;

/**
* Go back to the previous route in history.
*/
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/useNavigationHelpers.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import * as CommonActions from './CommonActions';
import NavigationContext from './NavigationContext';
import ResetRootContext from './ResetRootContext';
import { NavigationStateContext } from './NavigationContainer';
import { NavigationEventEmitter } from './useEventEmitter';
import {
Expand Down Expand Up @@ -36,6 +37,7 @@ export default function useNavigationHelpers<
Action extends NavigationAction,
EventMap extends { [key: string]: any }
>({ onAction, getState, emitter, router }: Options<State, Action>) {
const resetRoot = React.useContext(ResetRootContext);
const parentNavigationHelpers = React.useContext(NavigationContext);
const { performTransaction } = React.useContext(NavigationStateContext);

Expand Down Expand Up @@ -65,6 +67,7 @@ export default function useNavigationHelpers<
return {
...parentNavigationHelpers,
...helpers,
resetRoot,
dispatch,
emit: emitter.emit,
isFocused: parentNavigationHelpers
Expand All @@ -83,6 +86,7 @@ export default function useNavigationHelpers<
router,
getState,
parentNavigationHelpers,
resetRoot,
emitter.emit,
performTransaction,
onAction,
Expand Down

0 comments on commit e61f594

Please sign in to comment.