On Android phones, the back button is often used as a function, which can be used to return to the previous page, or to cancel an operation, etc. In short, it is very convenient. React Native (RN) project with React Navigation to handle the back button.
React Navigation? As it has become a standard part of RN’s project routing tools, the official RN documentation recommends using Expo for project creation, while Expo recommends using React Navigation for route management.
RN’s back button event
RN provides an API for handling BackHandler, which works much like other event listeners by passing in an event name and an event function, as shown in the following code:
|
|
Note: This differs from other event listeners in that a return Boolean is required, because the fallback button events are fired in reverse order, i.e. the last registered event is fired first. Return true means that the previous fallback button event is not called, whereas return false means that it is called.
This API is fine to use, but it can be tricky to add events to multiple components if they need to handle the fallback button event at the same time, and to pay attention to the event invocation relationships between components.
In addition, the back button events need to be added and removed in the component lifecycle methods mount and unmount:
|
|
However, some level 1 pages are resident in the routing stack, so when a page’s events are added, they will not be destroyed even if the page jumps, causing some performance loss.
React Navigation Processes the rollback event
The React Navigation handles the back button. Here is the official documentation. We can see that the React Navigation handles the back button in much the same way as RN does, but with the life cycle method of the component changed to React Navigation.
|
|
In the code we can see that React Navigation adds the back button event via the didFocus method (the callback after the page is loaded) and then removes the event via the willBlur method (the callback before the page leaves). This way, even if the page is resident on the routing stack, the back button event is removed whenever the page jumps.
There are still some issues with this approach. First, the page will still load events that cannot be removed, but instead of the back button event, the event will be listened on by React Navigation.
Another serious problem is: If enter and leave the page takes longer (such as the need to send web request) for several times, or switch pages faster, is likely to add the current page events (didFocus) to remove the last page (willBlur), which means that the current page in the back button events may be added immediately after being removed, The operation is abnormal.
A better solution
To summarize the above questions:
- Needs to be handled in multiple components (pages)
The back button
Event, which makes writing code cumbersome - The sequence of adding and deleting events may be distorted during page switching, resulting in abnormal App behavior
The main reason for the above problems is that the fallback button event is handled in multiple places, which could have been avoided if our APP had only one place to handle the fallback button event.
However, there are two issues that need to be addressed if the handling of the back button event is kept in one place:
- Where do you add it
The back button
Event? - How do we determine which page is currently on? Because we need to deal with different logic according to different pages, for example, the back button of page A needs to exit App, while page B needs to return to the previous page.
Where do you add itThe back button
Event?
To solve this problem, we can wrap a Layout component in the outermost layer of the component, and then use this component to add the event of the back button, and then use the original root component as the children of this component. Example:
|
|
There is no need to add back button events elsewhere, and all page events are handled in the handleBackPress method.
How to determine which page is the current page?
The React Navigation documentation provides a way to navigate without Navigation parameters. The idea here is to set the root node to get the global React Navigation object, and then call the React Navigation API from that object.
We can extend this method to get the current page by adding the following function:
|
|
We can get the route object of the current page, which can be used to determine the page based on routeName:
|
|
Direct use of
React Native Android Backer is an RN library based on the same ideas as the React Native Android Backer. You can also use the Readme in the library.
conclusion
This is a practical problems encountered in the RN development, began to refer to the various articles and methods are not very ideal, then found themselves through grope for solution, and its extract became a third-party library, also hope to be able to help to meet the same problem friend, you are welcome to try and leave a message, thank you.