首页 > 解决方案 > 如何根据用户的关键字实现搜索和过滤以显示对象列表中的数据?

问题描述

在此处输入图像描述

正如标题所说,我想实现以下模型,我有一个本地导入的 json 文件,我希望用户在搜索栏上写,根据用户写的文本,我希望 json 被过滤并显示在底部区域。我的 json 对象:

export const cards = [
    {
        img: 'https://media.emailonacid.com/wp-content/uploads/2019/05/EOA_MediaQueries2019_Blog.jpg',
        author: null,
        description: 'Liked Songs'
    },
    {
        img: 'https://i.scdn.co/image/ab67706c0000da845f2575c6513aa8e264879e7d',
        author: null,
        description: 'Essa Gelada Eu vou beber'
    },
    {
        img: 'https://vintageculture.com/wp-content/uploads/2020/04/Slow-Down-VC-e-Slow-Motion-Remix.jpg',
        author: null,
        description: 'Slow Down (feat. Jhon)'
    },
    {
        img: 'https://i.pinimg.com/474x/18/a3/b2/18a3b25cf87f439a5c0bc0fa7ae0ca54.jpg',
        author: null,
        description: 'Marilia Mendonça'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b273d77d08d4bb06171ce0fe2a0e',
        author: null,
        description: 'Jorge & Mateus'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b2738ddd20bf644f1d50adafad7b',
        author: null,
        description: 'All Around The World'
    },
]

export const recentlys = [
    {
        img: 'https://i.scdn.co/image/ab67616d0000b2738ddd20bf644f1d50adafad7b',
        author: 'R3AB',
        description: 'All Around The World'
    },
    {
        img: 'https://vintageculture.com/wp-content/uploads/2020/04/Slow-Down-VC-e-Slow-Motion-Remix.jpg',
        author: 'Vinatge Culture',
        description: 'Slow Down (feat. Jhon)'
    },
    {
        img: 'https://i.pinimg.com/474x/18/a3/b2/18a3b25cf87f439a5c0bc0fa7ae0ca54.jpg',
        author: 'Marilia Mendonça',
        description: 'Marilia Mendonça'
    },
    {
        img: 'https://i.scdn.co/image/ab67706c0000da845f2575c6513aa8e264879e7d',
        author: 'Jorge & Mateus',
        description: 'Essa Gelada Eu vou beber'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b273d77d08d4bb06171ce0fe2a0e',
        author: 'Jorge & Mateus',
        description: 'Jorge & Mateus'
    },
]

export const playlists = [
    {
        img: 'https://vintageculture.com/wp-content/uploads/2020/04/Slow-Down-VC-e-Slow-Motion-Remix.jpg',
        author: 'Vinatge Culture',
        description: 'Slow Down (feat. Jhon)'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b2738ddd20bf644f1d50adafad7b',
        author: 'R3AB',
        description: 'All Around The World'
    },
    {
        img: 'https://i.scdn.co/image/ab67706c0000da845f2575c6513aa8e264879e7d',
        author: 'Jorge & Mateus',
        description: 'Essa Gelada Eu vou beber'
    },
    {
        img: 'https://i.pinimg.com/474x/18/a3/b2/18a3b25cf87f439a5c0bc0fa7ae0ca54.jpg',
        author: 'Marilia Mendonça',
        description: 'Marilia Mendonça'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b273d77d08d4bb06171ce0fe2a0e',
        author: 'Jorge & Mateus',
        description: 'Jorge & Mateus'
    },
]

export const artists = [
    {
        img: 'https://i.scdn.co/image/ab67706c0000da845f2575c6513aa8e264879e7d',
        author: 'Jorge & Mateus',
        description: 'Essa Gelada Eu vou beber'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b2738ddd20bf644f1d50adafad7b',
        author: 'R3AB',
        description: 'All Around The World'
    },
    {
        img: 'https://vintageculture.com/wp-content/uploads/2020/04/Slow-Down-VC-e-Slow-Motion-Remix.jpg',
        author: 'Vintage Culture',
        description: 'Slow Down (feat. Jhon)'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b273d77d08d4bb06171ce0fe2a0e',
        author: 'Jorge & Mateus',
        description: 'Jorge & Mateus'
    },
    {
        img: 'https://i.pinimg.com/474x/18/a3/b2/18a3b25cf87f439a5c0bc0fa7ae0ca54.jpg',
        author: 'Marilia Mendonça',
        description: 'Marilia Mendonça'
    },
    {
        img: 'https://i.scdn.co/image/1fd90cd274102d458ec3a9243ced32e659738133',
        author: 'Calvin Harris',
        description: 'Your Daily Mix 1'
    },
    {
        img: 'https://i.scdn.co/image/5e79a3aa31ed34c951b607e26c0df690c0118fc8',
        author: 'KVSH',
        description: null
    },
    {
        img: 'https://i1.sndcdn.com/avatars-000494458926-ftqfqe-t500x500.jpg',
        author: 'R3AB',
        description: null
    },
    {
        img: 'https://i.scdn.co/image/82e6e7e4f318d0b2ba80b09d00db2552966f2fdc',
        author: 'Liu',
        description: 'Your Daily Mix 2'
    },
    {
        img: 'https://i.scdn.co/image/ab67706f000000026cac5751f488923a32f4ee79',
        author: 'Martin Garrix',
        description: null
    },
    {
        img: 'https://penews.com.br/wp-content/uploads/2019/10/vintge-e1571597522273.jpg',
        author: 'Vintage Culture',
        description: null
    },
    {
        img: 'https://i.scdn.co/image/339b4f2b8fa072d2130ad69cd603919e6279258e',
        author: 'ALOK',
        description: null
    },
]

以下是我编写的确切代码以及我想要实现该功能的位置:

import React, {useState} from 'react';
import {
  SafeAreaView,
  ScrollView,
  View,
  Text,
  TextInput,
  StyleSheet,
  Dimensions,
} from 'react-native';
import {TabView, SceneMap} from 'react-native-tab-view';
import Icon from 'react-native-vector-icons/FontAwesome';

import {cards} from '../../Data/Home';

const FirstRoute = () => <View style={[styles.scene]} />;

const SecondRoute = () => <View style={[styles.scene]} />;
const initialLayout = {width: Dimensions.get('window').width};
export default function Search() {
  const [search, setSearch] = useState({});
  const [index, setIndex] = React.useState(0);
  const [tmpCards] = useState(cards);
  const [routes] = React.useState([
    {key: 'first', title: 'Users'},
    {key: 'second', title: 'Videos'},
  ]);

  const renderScene = SceneMap({
    first: FirstRoute,
    second: SecondRoute,
  });

  const filteredData = () => {
    tmpCards.filter((user) => {
      console.log(
        tmpCards.description.toLowerCase().includes(search.toLowerCase()),
      );
    });
  };
  return (
    <SafeAreaView style={{flex: 1, backgroundColor: '#fff'}}>
      <View style={{padding: 10}}>
        <View style={{flexDirection: 'row', backgroundColor: '#D3D3D3'}}>
          <Icon
            name="search"
            size={20}
            style={{marginTop: 12, marginLeft: 5}}
          />

          <TextInput
            placeholder="Search"
            value={search}
            onChangeText={(search) => setSearch(search)}
            style={{marginLeft: 10}}
          />
          {filteredData.map((user, id) => {
            <Text>{tmpCards.description}</Text>;
          })}
        </View>
      </View>
      <TabView
        navigationState={{index, routes}}
        renderScene={renderScene}
        onIndexChange={setIndex}
        initialLayout={initialLayout}
        style={{backgroundColor: '#fff'}}
      />
    </SafeAreaView>
  );
}
const styles = StyleSheet.create({
  scene: {
    flex: 1,
  },
});

但是我收到了这个错误:

 TypeError: undefined is not a function (near '...filteredData.map...')

任何建议都会有所帮助。

标签: reactjsreact-nativereact-reduxreact-native-androidreact-native-flatlist

解决方案


您的代码有几个问题。根据您的要求, fitlerdata 方法没有返回任何内容,过滤器功能实现也是错误的。我稍微修改了你的代码。请立即尝试。

import React, { useState } from 'react';
import {
    SafeAreaView,
    ScrollView,
    View,
    Text,
    TextInput,
    StyleSheet,
    Dimensions,
} from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';
import Icon from 'react-native-vector-icons/FontAwesome';

import { cards } from '../../Data/Home';

const FirstRoute = () => <View style={[styles.scene]} />;

const SecondRoute = () => <View style={[styles.scene]} />;
const initialLayout = { width: Dimensions.get('window').width };
export default function Search() {
    const [search, setSearch] = useState({});
    const [index, setIndex] = React.useState(0);
    const [tmpCards] = useState(cards);
    const [routes] = React.useState([
        { key: 'first', title: 'Users' },
        { key: 'second', title: 'Videos' },
    ]);

    const renderScene = SceneMap({
        first: FirstRoute,
        second: SecondRoute,
    });

    const filteredData = () => tmpCards.filter((user) => user.description.toLowerCase().includes(search.toLowerCase()))
   

  return (
        <SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}>
            <View style={{ padding: 10 }}>
                <View style={{ flexDirection: 'row', backgroundColor: '#D3D3D3' }}>
                    <Icon
                        name="search"
                        size={20}
                        style={{ marginTop: 12, marginLeft: 5 }}
                    />

                    <TextInput
                        placeholder="Search"
                        value={search}
                        onChangeText={(search) => setSearch(search)}
                        style={{ marginLeft: 10 }}
                    />
                    {filteredData().map((user, id) =><Text>{user.description}</Text>)}
                </View>
            </View>
            <TabView
                navigationState={{ index, routes }}
                renderScene={renderScene}
                onIndexChange={setIndex}
                initialLayout={initialLayout}
                style={{ backgroundColor: '#fff' }}
            />
        </SafeAreaView>
    );
}
const styles = StyleSheet.create({
    scene: {
        flex: 1,
    },
});

推荐阅读