I am trying to implement Deep Linking in React Navigation 5 into my React Native 0.61 project, which was created via react-native init.
When the app is in the background, deep linking works. On my Android device, I can click on https://myproject.com/content/5 and the app correctly navigates to the content section and displays the content with an id of 5.
However, if I kill the app (or install it without opening it) and click on that same link I am taken to the home page instead of navigating to the appropriate content page.
The activity in my AndroidManifest.xml:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="myproject.com"/>
</intent-filter>
</activity>
The meat & potatoes of App.js:
const config = {
Content: {
path: "content/:id",
parse: {
id: Number
}
}
};
const App = () => {
const {state} = useContext(Context);
const ref = React.useRef();
const { getInitialState } = useLinking(ref, {
prefixes: ['http://myproject.com'],
config
});
const [isReady, setIsReady] = React.useState(false);
const [initialState, setInitialState] = React.useState();
useEffect(() => {
Promise.race([
getInitialState(),
new Promise(resolve => setTimeout(resolve, 150)),
])
.catch(e => {
console.error(e);
})
.then(state => {
if (state !== undefined) {
setInitialState(state);
}
setIsReady(true);
});
}, [getInitialState]);
return (
<NavigationContainer initialState={initialState} ref={ref} >
{state.isLoading || !isReady ?
(
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name="Loading" component={LoadingScreen} />
</Stack.Navigator>
)
:
<MainStack />
}
</NavigationContainer>
);
};
What should I do to have the app navigate to the content page when an Android user opens the app with the deep link, when the app has previously been killed?
I also would like to keep the current deep linking behavior where a deep link works when the app is in the background.
The issue is also explained here but none of the proposed solutions worked for me.
Your navigator has dynamic route switching, so what you need to do is handle all of switching logic first, and then render the navigator once the app is ready. Currently your navigator ignores the initialState
and dynamic switching overrides the route rendered.
Try moving your loading state outside of the navigator, or determine the app is ready to show the navigator in an effect
.