如何将一些数组方法应用于反应中的过滤器搜索

how to apply the some array method to a filter search in react

我正在使用 react 构建一个有趣的搜索功能,我有以下数据结构:

data.js

export const data = [
  {
    "id": 1,
    "first_name": "James",
    "last_name": "Wattson",
    "gender": "M",
    "age": 43,
    "country": "USA",

  },
...

列表数据

搜索查询结果

代码

const App = () => {

  const [query, setQuery] = useState("");
  const filterKeys = ["first_name", "last_name", "gender", "age", "country"]

  const handleOnChange = (event) => {
    const filterQuery = data.filter(value => value.first_name.toLowerCase().includes(event.target.value))

    setQuery(filterQuery);
  }

  const tableResults = query.length > 0 ? query : data;

  return (
    <div className="form">
      <div>
        <input placeholder="search..." onChange={handleOnChange}/>
      </div>
      <div>
        <Table data={tableResults}/>
      </div>
    </div>
  );
};


export default App

我的搜索功能运行良好,但仅限于 first_name 数据作为输入。

我怎样才能使用 .some() array method 更新 const filterQuery 变量逻辑,以便能够添加基于数组 filterKeys 字符串的过滤器,这些字符串是我可以搜索的附加键他们的价值观。

目标:能够搜索到每个键的值,包括:first_name、last_name、性别、年龄、国家。上面的代码只能搜索 first_name 值

像这样

const filterQuery = data.filter(value => filterKeys.some(key => value[key].toLowerCase().includes(event.target.value)));

但这似乎不正确...因为它在 chrome 控制台选项卡上打字时崩溃。错误 Uncaught TypeError: value[key].toLowerCase is not a function

如果您遇到此错误:

value[key].toLowerCase is not a function

...这意味着 value[key] 不是字符串(可能是 nullundefined 或数字?)。 “年龄”属性 就是这种情况,因为它似乎是数字。要静默处理这种情况,请将调用链接到 .toString 并使所有 属性 查找有条件,使用可选链接 (?.) 运算符:

value[key]?.toString()?.toLowerCase()?.includes(event.target.value)

有时候你会得到typeof value[key]个数字,数字没有方法toLowerCase(),所以你需要使用:

const filterQuery = data.filter(value => filterKeys.some(key => (value[key] + "").toLowerCase().includes(event.target.value)));

你的handleOnChange函数可能是这样的:

我的解决方案不使用 some 数组方法,只是另一种获取所需内容的方法(也不需要 filterKeys

  const handleOnChange = (event) => {
    const term = event.target.value;
    const filterQuery = data.filter((record) => {
      return (
        Object.values(record)
          .filter((r) => !Number.isInteger(r))
          .filter((r) => r.toLowerCase().includes(term)).length > 0
      );
    });

    setQuery(filterQuery);
  };

Object.values(record)会return记录对象的所有value,之后需要用filter查找哪条记录有value包含event.target.value.