小编典典

在FlatList上使用React Native搜索过滤器

reactjs

我正在尝试根据搜索栏文本搜索单位列表。我遇到的问题是,当用户键入错误时……说他们想键入“ burger”,但错误地键入了“
burget”,那么它什么也不会返回。当用户删除“ t”时,它应使用与“ burge”部分匹配的最后一个文本再次重新渲染该平面列表。

注意:使用react-native-elements搜索栏,该栏允许我仅使用e或event调用文本。

到目前为止,我在Main.js文件中拥有什么:

searchText = (e) => {
    let text = e.toLowerCase();
    let trucks = this.state.data;

    // search by food truck name
    let filteredName = trucks.filter((truck) => {
      return truck.name.toLowerCase().match(text); 
    });

    // if no match and text is empty
    if(!text || text === '') {
      console.log('change state');
        this.setState({
          data: initial
        });
      }
    // if no name matches to text output
    else if(!Array.isArray(filteredName) && !filteredName.length) {
      console.log("not name");
      this.setState({
        data: [],
      });
    }
    // if name matches then display
    else if(Array.isArray(filteredName)) {
      console.log('Name');
      this.setState({
        data: filteredName,
      });
    }
   };

<View style={styles.container}>
  <SearchBar
    round
    lightTheme
    containerStyle={styles.search}
    ref="search"
    textInputRef="searchText"
    onChangeText={this.searchText.bind(this)}
    placeholder='Search by Truck Name...'
   />
   <TruckList getTruck={(truck) => this.setTruck(truck)} truckScreen={this.truckScreen} data={this.state.data}/>
</View>

然后是TruckList.JS:

export default class TruckList extends Component {
    // rendering truck screen
    renderTruckScreen = (item) => {
        this.props.truckScreen();
        this.props.getTruck(item);
    }

    render() {
        return(
            <List style={styles.list}>
                <FlatList
                    data={this.props.data}
                    renderItem={({ item }) => (
                        <ListItem
                            roundAvatar
                            avatar={{uri: item.pic1}}
                            avatarStyle={styles.avatar}
                            title={item.name}
                            titleStyle={styles.title}
                            subtitle={
                                <View style={styles.subtitleView}>
                                    <Text style={styles.subtitleFood}>{item.food}</Text>
                                    <View style={styles.subtitleInfo}>
                                        <Icon 
                                            name="favorite"
                                            size={20}
                                            color={"#f44336"}
                                            style={styles.subtitleFavorite}
                                        />
                                        <Text style={styles.subtitleFavoriteText}>{item.favorited} favorited</Text>
                                    </View>
                                </View>
                            }
                            onPress={() => this.renderTruckScreen(item)}
                        />
                    )}
                    keyExtractor={(item) => item.uid}
                    ListFooterComponent={this.footer}
                />
            </List>
        )
      }
    }

我尝试了其他几种方法都无济于事。我看到的唯一用于React
Native的解决方案是使用ListView,它将随时间折旧。因此,我正在尝试使用新的FlatList组件执行此操作。

谢谢你的帮助!


阅读 278

收藏
2020-07-22

共1个答案

小编典典

今天,当我尝试在新的FlatList组件上实现过滤器/搜索功能时,遇到了同样的问题。这是我设法解决的方法:

通过在父组件状态下创建另一个名为noData的项,可以在没有与搜索匹配的结果时将其设置为true,然后有条件地呈现FlatList。

我的实现与您的实现略有不同,但是如果我不得不调整您的代码,它将看起来像这样:

Searchtext函数:

searchText = (e) => {
    let text = e.toLowerCase()
    let trucks = this.state.data
    let filteredName = trucks.filter((item) => {
      return item.name.toLowerCase().match(text)
    })
    if (!text || text === '') {
      this.setState({
        data: initial
      })
    } else if (!Array.isArray(filteredName) && !filteredName.length) {
      // set no data flag to true so as to render flatlist conditionally
      this.setState({
        noData: true
      })
    } else if (Array.isArray(filteredName)) {
      this.setState({
        noData: false,
        data: filteredName
      })
    }
  }

然后将noData bool传递给TruckList组件:

<TruckList getTruck={(truck) => this.setTruck(truck)} 
truckScreen={this.truckScreen} data={this.state.data} noData={this.state.noData}/>

然后仅在有结果的情况下在TruckList组件中呈现FlatList:

<List style={styles.list}>
{this.props.noData ? <Text>NoData</Text> : <FlatList {...} />}         
</List>

然后应该注意处理用户键入错误-因为它将在没有结果的情况下立即重新呈现该平面列表,并且在删除键入错误时会记住以前的搜索状态。

让我知道是否有帮助!

2020-07-22