Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement an application-wide search bar?

It seems to be a pretty common task to have an application-wide search bar in the header. Unfortunately, I haven't found some ready recipes on how to accomplish it the right way. My solution was to place a custom SearchBox component in the React Native Navigation header using headerTitle:

static navigationOptions = ({navigation}) => {
     headerTitle: () => (<SearchBox ... />)

It had its drawbacks, e.g. using "static" variables to pass state and behavior between the application and the component. But it worked so far. Now, after moving to RNN 4.1.1, it stopped working because of the specifics of how the header is implemented in the RNN:

enter image description here

TextInput now doesn't fill the header's width and doesn't handle the text input properly.

enter image description here

I am looking for a way to implement an application-wide search bar in RN, that features the following properties:

  • it appears application-wide;
  • its contents can be modified by a user, who wants to perform the search;
  • when the user navigates back its contents conform to the shown page (e.g. if the user typed a query on page A and then got redirected to page B, so when they go back to the page A the search box contains "Page A" and not the query they typed);
  • it supports suggestions (an also tricky thing to do).

Update

Ideally, I am looking for an answer that features the following aspects:

  • be React Navigation v5 specific;
  • tell how the search bar is implemented per se (e.g. passed as a component via header property in the above scenario);
  • show how the search bar communicates with the core application in the following scenarios:
    • a user submits a query;
    • search box query gets updated independently from the application (e.g. the user taps a TouchableOpacity and gets navigated to a new page);
  • how to ensure query consistency during the navigation. E.g. when the user goes back to the previous screen, the query in the search bar should match the screen contents.
  • how to implement suggestions (users can see their options while typing; options are loaded online from the remote source).
like image 433
Denis Kulagin Avatar asked Feb 06 '20 20:02

Denis Kulagin


Video Answer


1 Answers

You are almost done, but unfortunately, I think this is not possible with react-navigation 4. In latest, 5.0 which is now production-ready, you have to rewrite your stacks.

In 5.0, you can use the useFocusEffect which is nice to detect Back Actions. So, you have your header like this:

function SearchBar(props) {
  return (
    <TextInput />
  );
}

function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{ headerTitle: props => <SearchBar {...props} /> }}
      />
    </Stack.Navigator>
  );
}

The problem is, you have to repeat options and useFocusEffect logic on every screen.

Another approach could be:

  1. Disable all headers globally
  2. In all your screens, create a layout like this:
      <View style={{ flex: 1 }}>
        <MyAppbarHeader title={'PageA'} resetOnBack={false/true} />
        <View style={{ flex: 1, margin: 8 }}>
          <FlatList
            data={someDataOnMyScreen}
            renderItem={renderItem}
          />
        </View>
      </View>

In MyAppbarHeader you can pass the title as props, and other props like resetOnBack and implement the logic in this functional component.

like image 173
MBach Avatar answered Sep 28 '22 17:09

MBach