refactor: check for stale == false to determine if state is rehydrated

This commit is contained in:
satyajit.happy
2019-08-19 17:02:03 +05:30
parent 48bdbe43a9
commit 797b02bd8e
14 changed files with 35 additions and 29 deletions

View File

@@ -306,12 +306,10 @@ For example, the path `/rooms/chat?user=jane` will be translated to a state obje
```js
{
stale: true,
routes: [
{
name: 'rooms',
state: {
stale: true,
routes: [
{
name: 'chat',

View File

@@ -4,6 +4,7 @@ import * as BaseActions from '../BaseActions';
jest.mock('shortid', () => () => 'test');
const STATE = {
stale: false as false,
key: 'root',
index: 1,
routes: [
@@ -21,6 +22,7 @@ it('replaces focused screen with REPLACE', () => {
);
expect(result).toEqual({
stale: false,
key: 'root',
index: 1,
routes: [
@@ -39,6 +41,7 @@ it('replaces source screen with REPLACE', () => {
});
expect(result).toEqual({
stale: false,
key: 'root',
index: 1,
routes: [
@@ -66,6 +69,7 @@ it('sets params for the focused screen with SET_PARAMS', () => {
);
expect(result).toEqual({
stale: false,
key: 'root',
index: 1,
routes: [
@@ -84,6 +88,7 @@ it('sets params for the source screen with SET_PARAMS', () => {
});
expect(result).toEqual({
stale: false,
key: 'root',
index: 1,
routes: [

View File

@@ -296,7 +296,6 @@ it('handle resetting state with ref', () => {
render(element).update(element);
const state = {
stale: true,
index: 1,
routes: [
{

View File

@@ -20,6 +20,7 @@ export default function MockRouter(options: DefaultRouterOptions) {
: routeNames.indexOf(options.initialRouteName);
return {
stale: false,
key: String(MockRouterKey.current++),
index,
routeNames,
@@ -34,7 +35,7 @@ export default function MockRouter(options: DefaultRouterOptions) {
getRehydratedState(partialState, { routeNames, routeParamList }) {
let state = partialState;
if (!state.stale) {
if (state.stale === false) {
return state as NavigationState;
}

View File

@@ -6,17 +6,14 @@ it('converts path string to initial state', () => {
'foo/bar/baz%20qux?author=%22jane%20%26%20co%22&valid=true'
)
).toEqual({
stale: true,
routes: [
{
name: 'foo',
state: {
stale: true,
routes: [
{
name: 'bar',
state: {
stale: true,
routes: [
{
name: 'baz qux',
@@ -34,12 +31,10 @@ it('converts path string to initial state', () => {
it('handles leading slash when converting', () => {
expect(getStateFromPath('/foo/bar/?count=42')).toEqual({
stale: true,
routes: [
{
name: 'foo',
state: {
stale: true,
routes: [
{
name: 'bar',
@@ -54,12 +49,10 @@ it('handles leading slash when converting', () => {
it('handles ending slash when converting', () => {
expect(getStateFromPath('foo/bar/?count=42')).toEqual({
stale: true,
routes: [
{
name: 'foo',
state: {
stale: true,
routes: [
{
name: 'bar',
@@ -74,12 +67,10 @@ it('handles ending slash when converting', () => {
it('handles route without param', () => {
expect(getStateFromPath('foo/bar')).toEqual({
stale: true,
routes: [
{
name: 'foo',
state: {
stale: true,
routes: [{ name: 'bar' }],
},
},

View File

@@ -49,6 +49,7 @@ it('initializes state for a navigator on navigation', () => {
expect(onStateChange).toBeCalledTimes(1);
expect(onStateChange).toBeCalledWith({
stale: false,
index: 0,
key: '0',
routeNames: ['foo', 'bar', 'baz'],
@@ -140,6 +141,7 @@ it('initializes state for nested screens in React.Fragment', () => {
expect(onStateChange).toBeCalledTimes(1);
expect(onStateChange).toBeCalledWith({
stale: false,
index: 0,
key: '0',
routeNames: ['foo', 'bar', 'baz'],
@@ -189,6 +191,7 @@ it('initializes state for nested navigator on navigation', () => {
expect(onStateChange).toBeCalledTimes(1);
expect(onStateChange).toBeCalledWith({
stale: false,
index: 2,
key: '0',
routeNames: ['foo', 'bar', 'baz'],
@@ -199,6 +202,7 @@ it('initializes state for nested navigator on navigation', () => {
key: 'baz',
name: 'baz',
state: {
stale: false,
index: 0,
key: '1',
routeNames: ['qux'],
@@ -302,6 +306,7 @@ it('cleans up state when the navigator unmounts', () => {
expect(onStateChange).toBeCalledTimes(1);
expect(onStateChange).lastCalledWith({
stale: false,
index: 0,
key: '0',
routeNames: ['foo', 'bar'],
@@ -353,6 +358,7 @@ it('allows arbitrary state updates by dispatching a function', () => {
expect(onStateChange).toBeCalledTimes(1);
expect(onStateChange).toBeCalledWith({
stale: false,
index: 1,
key: '0',
routeNames: ['foo', 'bar'],
@@ -390,6 +396,7 @@ it('updates route params with setParams', () => {
expect(onStateChange).toBeCalledTimes(1);
expect(onStateChange).lastCalledWith({
stale: false,
index: 0,
key: '0',
routeNames: ['foo', 'bar'],
@@ -403,6 +410,7 @@ it('updates route params with setParams', () => {
expect(onStateChange).toBeCalledTimes(2);
expect(onStateChange).lastCalledWith({
stale: false,
index: 0,
key: '0',
routeNames: ['foo', 'bar'],
@@ -441,6 +449,7 @@ it('handles change in route names', () => {
);
expect(onStateChange).toBeCalledWith({
stale: false,
index: 0,
key: '0',
routeNames: ['foo', 'baz', 'qux'],

View File

@@ -75,6 +75,7 @@ it("lets parent handle the action if child didn't", () => {
expect(onStateChange).toBeCalledTimes(1);
expect(onStateChange).lastCalledWith({
stale: false,
index: 2,
key: '0',
routeNames: ['foo', 'bar', 'baz'],

View File

@@ -18,7 +18,6 @@ export default function getStateFromPath(
while (segments.length) {
const state = {
stale: true,
routes: [{ name: decodeURIComponent(segments[0]) }],
};

View File

@@ -24,20 +24,19 @@ export type NavigationState = {
/**
* Whether the navigation state has been rehydrated.
*/
stale?: false;
stale: false;
};
export type InitialState = Partial<
Omit<NavigationState, 'stale' | 'routes'>
> & {
stale?: boolean;
routes: Array<Omit<Route<string>, 'key'> & { state?: InitialState }>;
};
export type PartialState<State extends NavigationState> = Partial<
Omit<State, 'stale' | 'key' | 'routes' | 'routeNames'>
> & {
stale?: boolean;
stale?: true;
routes: Array<
Omit<Route<string>, 'key'> & { key?: string; state?: InitialState }
>;
@@ -128,7 +127,7 @@ export type Router<
* @param options.routeParamsList Object containing params for each route.
*/
getRehydratedState(
partialState: PartialState<State>,
partialState: PartialState<State> | State,
options: {
routeNames: string[];
routeParamList: ParamListBase;

View File

@@ -162,7 +162,7 @@ export default function useNavigationBuilder<
// If the state isn't initialized, or stale, use the state we initialized instead
// The state won't update until there's a change needed in the state we have initalized locally
// So it'll be `undefined` or stale untill the first navigation event happens
currentState === undefined || currentState.stale
currentState === undefined || currentState.stale !== false
? (initializedStateRef.current as State)
: (currentState as State);
@@ -201,7 +201,7 @@ export default function useNavigationBuilder<
const getState = React.useCallback((): State => {
const currentState = getCurrentState();
return currentState === undefined || currentState.stale
return currentState === undefined || currentState.stale !== false
? (initializedStateRef.current as State)
: (currentState as State);
}, [getCurrentState]);

View File

@@ -72,13 +72,11 @@ export default function App() {
const state = getStateFromPath(path);
return {
stale: true,
routes: [
{
name: 'root',
state: {
...state,
stale: true,
routes: [{ name: 'home' }, ...(state ? state.routes : [])],
},
},

View File

@@ -55,6 +55,7 @@ export default function DrawerRouter(
: routeNames.indexOf(options.initialRouteName);
return {
stale: false,
key: `drawer-${shortid()}`,
index,
routeNames,
@@ -69,8 +70,8 @@ export default function DrawerRouter(
},
getRehydratedState(partialState, { routeNames, routeParamList }) {
if (!partialState.stale) {
return partialState as DrawerNavigationState;
if (partialState.stale === false) {
return partialState;
}
const state = router.getRehydratedState(partialState, {

View File

@@ -54,6 +54,7 @@ export default function StackRouter(options: StackRouterOptions) {
: routeNames[0];
return {
stale: false,
key: `stack-${shortid()}`,
index: 0,
routeNames,
@@ -70,8 +71,8 @@ export default function StackRouter(options: StackRouterOptions) {
getRehydratedState(partialState, { routeNames, routeParamList }) {
let state = partialState;
if (!state.stale) {
return state as StackNavigationState;
if (state.stale === false) {
return state;
}
const routes = state.routes

View File

@@ -2,6 +2,7 @@ import shortid from 'shortid';
import {
CommonAction,
BaseRouter,
PartialState,
NavigationState,
DefaultRouterOptions,
Router,
@@ -60,6 +61,7 @@ export default function TabRouter({
: routeNames.indexOf(initialRouteName);
return {
stale: false,
key: `tab-${shortid()}`,
index,
routeNames,
@@ -75,12 +77,14 @@ export default function TabRouter({
getRehydratedState(partialState, { routeNames, routeParamList }) {
let state = partialState;
if (!state.stale) {
return state as TabNavigationState;
if (state.stale === false) {
return state;
}
const routes = routeNames.map(name => {
const route = state.routes.find(r => r.name === name);
const route = (state as PartialState<TabNavigationState>).routes.find(
r => r.name === name
);
return {
...route,