You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native:基于嵌套JSON实现技能搜索FlatList的问题求助

实现React Native中按技能搜索员工的FlatList

我帮你修改代码来实现技能搜索功能,核心思路是先把员工数据扁平化为每个技能对应一个条目,这样不管是搜索员工姓名还是技能名称,都能方便地过滤出匹配的结果。以下是修改后的完整代码:

// Searching using Search Bar Filter in React Native List View

// import React in our code
import React, { useState, useEffect } from "react";

// import all the components we are going to use
import {
  SafeAreaView,
  Text,
  StyleSheet,
  View,
  FlatList,
  TextInput,
  Image,
  TouchableOpacity,
} from "react-native";

// import employee json
import employeeList from "../json/employee";


const AllListScreen = ({ navigation, route }) => {
  const [search, setSearch] = useState("");
  const [filteredDataSource, setFilteredDataSource] = useState([]);
  const [masterDataSource, setMasterDataSource] = useState([]);

  // 初始化:将员工数据扁平化为「员工+技能」的条目数组
  useEffect(() => {
    const flatSkillItems = employeeList.flatMap(employee => 
      employee.skills.map(skill => ({
        employee,
        skill
      }))
    );
    setFilteredDataSource(flatSkillItems);
    setMasterDataSource(flatSkillItems);
  }, []);

  
  const searchFilterFunction = (text) => {
    if (text) {
      const upperSearchText = text.toUpperCase();
      // 过滤匹配员工姓名 或 技能名称的条目
      const newData = masterDataSource.filter(item => {
        const employeeName = item.employee.name.toUpperCase();
        const skillName = item.skill.name.toUpperCase();
        return employeeName.includes(upperSearchText) || skillName.includes(upperSearchText);
      });
      setFilteredDataSource(newData);
      setSearch(text);
    } else {
      // 搜索为空时恢复全部数据
      setFilteredDataSource(masterDataSource);
      setSearch(text);
    }
  };

  const ItemView = ({ item }) => {
    const { employee, skill } = item;
    return (
      <TouchableOpacity
        onPress={() => console.log(`选中技能:${skill.name}`)}
        style={styles.itemStyle}
      >
        <Image
          source={employee.image} // 使用员工自身的头像图片
          style={{ height: 50, width: 50, borderRadius: 25 }} // 可选:添加圆角更美观
        />
        <View style={styles.textPortion}>
          <Text style={styles.employeeName}>{employee.name}</Text>
          <Text style={styles.skillName}>{skill.name.toUpperCase()}</Text>
        </View>
      </TouchableOpacity>
    );
  };

  const ItemSeparatorView = () => {
    return (
      <View
        style={{
          height: 0.5,
          width: "100%",
          backgroundColor: "#C8C8C8",
        }}
      />
    );
  };

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <View style={styles.container}>
        <TextInput
          style={styles.textInputStyle}
          onChangeText={(text) => searchFilterFunction(text)}
          value={search}
          underlineColorAndroid="transparent"
          placeholder="搜索员工姓名或技能"
        />
        <FlatList
          data={filteredDataSource}
          keyExtractor={(item) => `${item.employee.id}-${item.skill.id}`} // 用员工+技能的唯一组合作为key
          renderItem={ItemView}
          ItemSeparatorComponent={ItemSeparatorView} // 统一设置条目分隔符
        />
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#FFFFFF",
    flex: 1,
  },
  itemStyle: {
    flex: 1,
    padding: 8,
    flexDirection: "row",
    alignItems: "center",
  },
  textInputStyle: {
    height: 50,
    borderWidth: 1,
    paddingLeft: 20,
    margin: 6,
    borderColor: "#009688",
    backgroundColor: "#FFFFFF",
    borderRadius: 5,
  },
  textPortion: {
    flexWrap: "wrap",
    flexShrink: 1,
    marginLeft: 12,
  },
  employeeName: {
    fontSize: 16,
    fontWeight: "500",
  },
  skillName: {
    fontSize: 14,
    color: "#666",
    marginTop: 4,
  },
});

export default AllListScreen;

关键修改说明:

  1. 数据扁平化处理
    原代码直接用员工数组作为数据源,现在我们通过flatMap将每个员工的技能拆分为独立条目,形成[{employee, skill}, ...]的结构,这样搜索时可以直接针对每个技能条目进行匹配,完美契合你"展示拥有对应技能的员工姓名(无需去重)"的需求。

  2. 搜索逻辑升级
    修改searchFilterFunction,同时检查员工姓名和技能名称是否包含搜索文本,支持双向搜索(既搜员工也搜技能),输入任意关键词都能得到精准结果。

  3. 渲染优化

    • 修正了头像图片的引用,现在使用员工自身的image字段(原代码用了随机图)
    • 给FlatList设置ItemSeparatorComponent来统一处理分隔符,避免原代码中最后一个条目多余的分隔线
    • 用员工id+技能id作为唯一key,彻底解决渲染时的key冲突问题
  4. 样式细节优化
    添加了员工姓名和技能名称的差异化样式,提升可读性;给头像添加圆角,让界面更美观友好。

这样修改后,你输入技能名称(比如"Cooking"),就会显示所有拥有该技能的员工条目;输入员工姓名(比如"John"),也能显示该员工的所有技能条目,完全满足你的需求。

内容的提问来源于stack exchange,提问作者Dof

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 10:31:14