Navigation in React Native is Broken

Graham Mendick
3 min readJun 17, 2019

--

React Native makes two promises on its homepage. The first promise is ‘you get an app that uses the same fundamental UI building blocks as regular Android and iOS apps’. The second is ‘it uses the same design as React, letting you compose a rich mobile UI using declarative components’. The problem is that the two go-to libraries for navigation break these promises. React Navigation breaks the first and React Native Navigation breaks the second. You’ll see how they break these promises when I try to add a search bar to the navigation bar on iOS. I’ll introduce the Navigation router, a new navigation library and the first to keep both the promises of React Native.

Search Me

The search bar is a feature of the iOS platform. It’s a text input that appears below the title in the navigation bar. When tapped, it slides up to take the place of the title and a ‘Cancel’ button flies in to nestle alongside. React Navigation doesn’t come with a search bar because it breaks the first promise of React Native. Instead of using the same fundamental building blocks as a regular iOS app, React Navigation builds its UX out of animated View components. If you want to display a search bar you’ll have to replicate the iOS functionality by animating View components too. A Sisyphean task. If you manage to roll your own search bar to the top of the hill, Apple will roll it back down again every time they revamp the navigation bar.

With React Native Navigation there’s good news and bad news. The good news is you can display a search bar because React Native Navigation uses the same fundamental building blocks as a regular iOS app. The bad news is there’s no SearchBar component because React Native Navigation breaks the second promise of React Native. Instead of letting you compose the UI using declarative components, you enable the search bar inside of a static config options object. There’s no placeholder prop, for example, that sets the text whenever the search input is empty. You’re forced to treat updates to the search bar like side effects by merging in your changed static configuration values.

class SearchScreen extends Component {
static options() {
return {
topBar: {
searchBar: true,
searchBarPlaceholder: 'Name',
}
};
}
searchBarUpdated({text}) {
this.setState({ text });
}
render() {
// render search results
}
}

The Search is Over

The Navigation router is the first navigation library that keeps the two promises of React Native. It keeps the first promise because it uses the same fundamental navigation building blocks as regular Android and iOS apps. You don’t have to replicate the search bar functionality in JavaScript like you would with React Navigation. The Navigation router keeps the second promise by letting you compose the UI using declarative components. It provides a SearchBar component so you don’t have to make the static function calls that React Native Navigation requires. Treat the component like a TextInput and trigger a setState whenever the onChangeText fires. Render your search results as children of the SearchBar and iOS will display them over the top of your main screen.

import { SearchBarIOS } from 'navigation-react-native';<SearchBarIOS
text={text}
placeholder=”Name”
onChangeText={text => this.setState({ text })}>
{/* render search results */}
</SearchBarIOS>

--

--