React recommends keeping the UI tree (React lib instance) cognizant of all changes.
This is the primary reason why window.location and such things are generally discouraged if you're using React Router, one should prefer the lib.
This works fine for majority of stuff
Problem - hooks and JS utils function
An app also has many util functions (JSX is absent here, only JS). There's also networking libs, that cannot be part of the UI tree. Example - axios instance.
Hooks - hooks can be called only inside components. So these util functions can never access them (they can if you pass it in components - dependency inversion, but that's too much code generally).
Specific problem (axios interceptor redirects to Screen seems hard)
Redirection in RN apps is a major issue (since window.location is absent), and React Navigaton functions can only be called on registered Screens or via the hook.
Lets take example of axios. It's not related to React, and is generally it's own file in an app.
So axios intereceptors (out of tree code) cannot forcibly navigate the app (on some auth invalid state).
Solution - instance services
Create some state in the app (in Node, instead of React), and make sure it's updated continually by the tree.
Simply said, just create an object with get and set in a .js and export it.
The App.js uses the set here to update the state. And now, get can be used by anywhere (tree or not).
import { createNavigationContainerRef } from "@react-navigation/native";
let navigator = createNavigationContainerRef(); // module state
/**
* Used by UI root (App.js), not for feature use.
*/
export function setNavigator(navigatorRef) {
navigator = navigatorRef;
}
/**
* `window.location` replacement for mobile. Call from anywhere, including outside components.
*
* Used by axios, util functions. Usable for feature use.
* note: don't use inside components. Use proper ReactNavigator functions, hooks.
*
* @link https://reactnavigation.org/docs/navigating-without-navigation-prop#usage
*/
export function getNavigator() {
if (!navigator.isReady()) {
console.warn("navigator not ready for use!");
return null;
}
return navigator;
}
Note
Such services should be used in out-of-tree code only. It's more in line with React's philosophy (stick to hooks and other constructs inside components).
I know that
React recommends keeping the UI tree (React lib instance) cognizant of all changes. This is the primary reason why
window.location
and such things are generally discouraged if you're using React Router, one should prefer the lib.This works fine for majority of stuff
Problem - hooks and JS utils function
Specific problem (axios interceptor redirects to Screen seems hard)
Redirection in RN apps is a major issue (since window.location is absent), and React Navigaton functions can only be called on registered Screens or via the hook.
Lets take example of axios. It's not related to React, and is generally it's own file in an app. So axios intereceptors (out of tree code) cannot forcibly navigate the app (on some auth invalid state).
Solution - instance services
Create some state in the app (in Node, instead of React), and make sure it's updated continually by the tree. Simply said, just create an object with get and set in a .js and export it. The App.js uses the
set
here to update the state. And now,get
can be used by anywhere (tree or not).Fortunately for ReactNavigation, it provides a way to create such a service. See https://reactnavigation.org/docs/navigating-without-navigation-prop#usage
Code:
Note
Such services should be used in out-of-tree code only. It's more in line with React's philosophy (stick to hooks and other constructs inside components).