简体   繁体   English

如何实现应用程序范围的搜索栏?

[英]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:我的解决方案是使用headerTitle在 React Native Navigation 标头中放置一个自定义SearchBox组件

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

It had its drawbacks, eg 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:现在,在迁移到 RNN 4.1.1 后,它停止工作,因为在 RNN 中如何实现标头的细节:

在此处输入图片说明

TextInput now doesn't fill the header's width and doesn't handle the text input properly. TextInput 现在不会填充标题的宽度并且不能正确处理文本输入。

在此处输入图片说明

I am looking for a way to implement an application-wide search bar in RN, that features the following properties:我正在寻找一种在 RN 中实现应用程序范围搜索栏的方法,它具有以下属性:

  • 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 (eg 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);当用户导航回其内容符合显示的页面时(例如,如果用户在页面 A 上键入查询,然后重定向到页面 B,因此当他们返回页面 A 时,搜索框包含“页面 A”而不是他们输入的查询);
  • 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;特定于 React Navigation v5;
  • tell how the search bar is implemented per se (eg passed as a component via header property in the above scenario);说明搜索栏本身是如何实现的(例如,在上述场景中通过header属性作为组件传递);
  • 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 (eg the user taps a TouchableOpacity and gets navigated to a new page);搜索框查询独立于应用程序更新(例如,用户点击 TouchableOpacity 并导航到新页面);
  • how to ensure query consistency during the navigation.如何保证导航过程中查询的一致性。 Eg 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).如何实施建议(用户可以在打字时看到他们的选项;选项是从远程源在线加载的)。

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.你快完成了,但不幸的是,我认为这在 react-navigation 4 中是不可能的。在最新的 5.0 中,现在可以生产了,你必须重写你的堆栈。

In 5.0, you can use the useFocusEffect which is nice to detect Back Actions .在 5.0 中,您可以使用useFocusEffect来检测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.问题是,您必须在每个屏幕上重复选项和 useFocusEffect 逻辑。

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.MyAppbarHeader您可以将标题作为道具传递,以及其他道具(如 resetOnBack)并在此功能组件中实现逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM