Skip to content

Commit

Permalink
feat: expose getActionForState in linking
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Dec 13, 2020
1 parent 3c87419 commit c9a5d45
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 9 deletions.
10 changes: 9 additions & 1 deletion packages/native/src/types.tsx
@@ -1,6 +1,7 @@
import type {
getStateFromPath as getStateFromPathDefault,
getPathFromState as getPathFromStateDefault,
getActionFromState as getActionFromStateDefault,
PathConfigMap,
Route,
} from '@react-navigation/core';
Expand Down Expand Up @@ -90,11 +91,18 @@ export type LinkingOptions = {
) => undefined | void | (() => void);
/**
* Custom function to parse the URL to a valid navigation state (advanced).
* This state object will be passed as `initialState` for initial URL,
* and converted to an action object to `dispatch` for subsequent URLs.
*/
getStateFromPath?: typeof getStateFromPathDefault;
/**
* Custom function to convert the state object to an action to dispatch (advanced).
* By default, the state is converted to a `NAVIGATE` action.
*/
getActionFromState?: typeof getActionFromStateDefault;
/**
* Custom function to convert the state object to a valid URL (advanced).
* Only applicable on Web.
* Used for creating links for navigation, primarily useful on Web.
*/
getPathFromState?: typeof getPathFromStateDefault;
};
Expand Down
14 changes: 10 additions & 4 deletions packages/native/src/useLinking.native.tsx
@@ -1,12 +1,12 @@
import * as React from 'react';
import { Linking, Platform } from 'react-native';
import {
getActionFromState,
getActionFromState as getActionFromStateDefault,
getStateFromPath as getStateFromPathDefault,
NavigationContainerRef,
} from '@react-navigation/core';
import type { LinkingOptions } from './types';
import escapeStringRegexp from 'escape-string-regexp';
import type { LinkingOptions } from './types';

let isUsingLinking = false;

Expand All @@ -33,6 +33,7 @@ export default function useLinking(
return () => Linking.removeEventListener('url', callback);
},
getStateFromPath = getStateFromPathDefault,
getActionFromState = getActionFromStateDefault,
}: LinkingOptions
) {
React.useEffect(() => {
Expand Down Expand Up @@ -66,14 +67,16 @@ export default function useLinking(
const configRef = React.useRef(config);
const getInitialURLRef = React.useRef(getInitialURL);
const getStateFromPathRef = React.useRef(getStateFromPath);
const getActionFromStateRef = React.useRef(getActionFromState);

React.useEffect(() => {
enabledRef.current = enabled;
prefixesRef.current = prefixes;
configRef.current = config;
getInitialURLRef.current = getInitialURL;
getStateFromPathRef.current = getStateFromPath;
}, [config, enabled, prefixes, getInitialURL, getStateFromPath]);
getActionFromStateRef.current = getActionFromState;
});

const extractPathFromURL = React.useCallback((url: string) => {
for (const prefix of prefixesRef.current) {
Expand Down Expand Up @@ -134,7 +137,10 @@ export default function useLinking(
return;
}

const action = getActionFromState(state, configRef.current);
const action = getActionFromStateRef.current(
state,
configRef.current
);

if (action !== undefined) {
try {
Expand Down
14 changes: 10 additions & 4 deletions packages/native/src/useLinking.tsx
Expand Up @@ -2,9 +2,9 @@ import * as React from 'react';
import {
getStateFromPath as getStateFromPathDefault,
getPathFromState as getPathFromStateDefault,
getActionFromState as getActionFromStateDefault,
NavigationContainerRef,
NavigationState,
getActionFromState,
} from '@react-navigation/core';
import { nanoid } from 'nanoid/non-secure';
import ServerContext from './ServerContext';
Expand Down Expand Up @@ -134,7 +134,7 @@ const createMemoryHistory = () => {
// - There's history to go back, `history.go` is called, and `popstate` fires
// - `history.go` is called multiple times, we need to resolve on respective `popstate`
// - No history to go back, but `history.go` was called, browser has no API to detect it
return new Promise((resolve, reject) => {
return new Promise<void>((resolve, reject) => {
const done = (interrupted?: boolean) => {
clearTimeout(timer);

Expand Down Expand Up @@ -293,6 +293,7 @@ export default function useLinking(
config,
getStateFromPath = getStateFromPathDefault,
getPathFromState = getPathFromStateDefault,
getActionFromState = getActionFromStateDefault,
}: LinkingOptions
) {
React.useEffect(() => {
Expand Down Expand Up @@ -323,14 +324,16 @@ export default function useLinking(
const enabledRef = React.useRef(enabled);
const configRef = React.useRef(config);
const getStateFromPathRef = React.useRef(getStateFromPath);
const getActionFromStateRef = React.useRef(getActionFromState);
const getPathFromStateRef = React.useRef(getPathFromState);

React.useEffect(() => {
enabledRef.current = enabled;
configRef.current = config;
getStateFromPathRef.current = getStateFromPath;
getActionFromStateRef.current = getActionFromState;
getPathFromStateRef.current = getPathFromState;
}, [config, enabled, getPathFromState, getStateFromPath]);
});

const server = React.useContext(ServerContext);

Expand Down Expand Up @@ -412,7 +415,10 @@ export default function useLinking(
}

if (index > previousIndex) {
const action = getActionFromState(state, configRef.current);
const action = getActionFromStateRef.current(
state,
configRef.current
);

if (action !== undefined) {
try {
Expand Down

0 comments on commit c9a5d45

Please sign in to comment.