I set up the react-native app with react-native-web. In this app I need to have navigation, so I added react-navigation/native package according to the getting started guide. In mobile platforms everything works well, but in browser navigation doesn't work as expected. When I just start the app, I can navigate from one page to another without any problem. But when I refresh any page, navigation returns me back to the first Stack.Screen component in Stack.Navigator list. And then, when I click on the Link to another page, nothing happens, no errors appears in console and route doesn't change.
So the navigation only works properly when I just launch the app and don't change the route and don't refresh the page.
Here my linking. I followed the deep linking guide
const linking: LinkingOptions<{
Auth: string;
Home: string;
Table: string;
Loading: string;
}> = {
prefixes: ['alfateacherapp://', 'http://'],
config: {
initialRouteName: 'Loading',
screens: {
Auth: 'auth',
Home: 'home',
Table: 'table',
Loading: 'loading',
},
},
};
Here my NavigationContainer:
<NavigationContainer linking={linking} fallback={<Loading />}>
<Stack.Navigator screenOptions={{ headerShown: false }}>
{isLoadedToken ? (
token ? (
// Screens for logged in users
<Stack.Group>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Table" component={Table} />
</Stack.Group>
) : (
// Auth screens
<Stack.Group>
<Stack.Screen name="Auth" component={Auth} />
</Stack.Group>
)
) : (
<Stack.Screen name="Loading" component={Loading} />
)}
</Stack.Navigator>
</NavigationContainer>
In Home and Table screens I just have the Link from react-navigation/native and Text from react-native. Home:
<Text>Home</Text>
<Link to={{ screen: 'Table' }}>Link to Table</Link>
Table:
<Text>Table</Text>
<Link to={{ screen: 'Home' }}>Link to Home</Link>
How can I fix this behavior? I need to be able to refresh the page and stay on current route when I'm in browser.
I figured it out! There was some platform-specific code for rendering a web index file. The rootTag displayed the usual react App component when the platform was "web" and AppRegistry from react-native registered the app in all other cases. This was done to bypass the warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead.
AppRegistry.registerComponent('Teacher', () => App);
if (Platform.OS === 'web') {
const rootTag = createRoot(document.getElementById('root'));
rootTag.render(<App />);
} else {
AppRegistry.runApplication('Teacher', {
initialProps: {},
rootTag: document.getElementById('root'),
});
}
When I removed this condition and left only the way that react-native handles the application, everything started working properly.
AppRegistry.registerComponent('Teacher', () => App);
AppRegistry.runApplication('Teacher', {
initialProps: {},
rootTag: document.getElementById('root'),
});