React Navigation: Working with Params
What's React navigation?
Unlike a web browser - where a link is simply made using an anchor <a>
tag, and the URL is pushed to the browser history stack - React Native doesn't have a built-in feature of a global history stack.
In most cases, mobile apps are made up of multiples screens. To manage the presentation and transitions of all these screens, usually a navigator is employed.
The most common solution is React Navigation, probably the most accepted and used library in the community.
React Navigation provides an uncomplicated solution for various navigation patterns, for instance, stack navigation and tabbed navigation.
Common Stack (or Native) Navigation
This method stacks screens on top of each other. When navigating to a new screen, it is pushed onto the stack, and navigates back by popping out the stack.
It's similar to a call stack in programming. This pattern is ideal for workflows where moving forward and backward through different screens.
Tab Navigation
This method uses tabs to switch between different screens or sections of the app. Each tab is usually associated with a different stack or set of screens.
Users can switch between tabs without affecting the state of other tabs. This pattern is commonly used for organising app content into distinct categories.
Understanding Params
When navigating between screens in a stack, it's possible to pass parameters to the new screens. Basically, you can pass data.
This is done using the
navigate
function and specifying the params.The next screen receives the data and can be accessed by
route.params
.
navigation.navigate("routeName", { itemId: id});
// in the next screen
const {itemId} = route.params
What should be in params
It's important to understand what data should be passed as params. They only contain the essential information to configure what is displayed on the screen.
I like the analogy provided in the documentation:
You can also think of the route object like a URL. If your screen had a URL, what should be in the URL? Params shouldn't contain data that you think should not be in the URL.
At first, I thought passing data through params was similar to passing down props through components, where the best practice is to pass the entire object and destructure inside the child component.
I was happy passing objects and even functions until I got a big warning:
Non-serializable values were found in the navigation state. This can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params.
Then I decided to investigate and, as you might expect, I was doing wrong.
We are often tempted to pass all kind of data in params, such as:
// Don't do this
navigation.navigate('FlatDetails', {
flat: {
id: 1,
district: 'Mitte',
price: 900,
},
});
This approach seems convenient, allowing direct access to flat objects with route.params.flat
. However, it is considered an anti-pattern. User data and similar objects should live in the global store instead of the navigation state. Storing data in the navigation state can result in duplicated data across different places, leading to issues like the flat screen displaying outdated information if the flat object changes after navigation.
A better approach is to pass only the ID of the flat in params:
navigation.navigate('FlatDetails', { flatId: 1 });
Now, flatId
can be used to grab the flat from your global store. This eliminates a host of issues such as outdated data, or problematic URLs.
Summary
In conclusion, React Navigation is a great tool for managing screen transitions in React Native apps. Understanding how to work with params, you can efficiently pass essential data between screens, ensuring a smooth user experience.
Remember to keep navigation state minimal and avoid passing non-serializable values. Often just an object ID rather than the entire object. Keep your application data separate from the navigation state to avoid potential bugs.
Subscribe to my newsletter
Read articles from José Copeti directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
José Copeti
José Copeti
Frontend Developer