mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-04-24 20:45:28 +08:00
feat: expose getActionForState in linking
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type {
|
||||
getStateFromPath as getStateFromPathDefault,
|
||||
getPathFromState as getPathFromStateDefault,
|
||||
getActionFromState as getActionFromStateDefault,
|
||||
PathConfigMap,
|
||||
Route,
|
||||
} from '@react-navigation/core';
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -33,6 +33,7 @@ export default function useLinking(
|
||||
return () => Linking.removeEventListener('url', callback);
|
||||
},
|
||||
getStateFromPath = getStateFromPathDefault,
|
||||
getActionFromState = getActionFromStateDefault,
|
||||
}: LinkingOptions
|
||||
) {
|
||||
React.useEffect(() => {
|
||||
@@ -66,6 +67,7 @@ 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;
|
||||
@@ -73,7 +75,8 @@ export default function useLinking(
|
||||
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) {
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
@@ -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);
|
||||
|
||||
@@ -293,6 +293,7 @@ export default function useLinking(
|
||||
config,
|
||||
getStateFromPath = getStateFromPathDefault,
|
||||
getPathFromState = getPathFromStateDefault,
|
||||
getActionFromState = getActionFromStateDefault,
|
||||
}: LinkingOptions
|
||||
) {
|
||||
React.useEffect(() => {
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user