React类组件转函数组件报错TypeError: users.filter is not a function求助
问题根因
你收到TypeError: users.filter is not a function报错的核心原因是函数组件中useState的状态更新逻辑和类组件的setState不一样:类组件的setState会自动合并state对象的顶层属性,但是useState每个状态是独立的,调用更新函数时传入什么值就会把对应状态直接覆盖成什么值。你在多个地方错误地把对象赋值给本来应该是数组类型的状态,导致原本是数组的users、filteredUsers被改成了对象,自然没有数组的filter方法。
具体需要修改的错误点
useEffect里的状态更新错误
你原来的写法是调用setUsers时传入了一个包含users和filteredUsers两个属性的对象,直接把users状态从数组改成了对象。应该分别调用setUsers和setFilteredUsers更新两个独立状态:
错误写法:
正确写法:setUsers({ users: results.data.results, filteredUsers: results.data.results, });setUsers(results.data.results); setFilteredUsers(results.data.results);handleSort里的状态更新错误
你原来调用setFilteredUsers时传入了一个带filteredUsers属性的对象,把数组改成了对象,另外setOrder的传参写法也不规范,同时sort是原地修改数组的方法,最好先拷贝数组再排序避免直接修改原状态:
错误写法:
正确写法:setOrder((order = "ascend")); // ... const sortedUsers = filteredUsers.sort(compareFnc); setFilteredUsers({ filteredUsers: sortedUsers });setOrder(order === "descend" ? "ascend" : "descend"); // ... const sortedUsers = [...filteredUsers].sort(compareFnc); setFilteredUsers(sortedUsers);handleSearchChange里的状态更新写法不规范
你原来的setFilteredUsers传参写法不符合规范,应该直接传过滤后的数组:
错误写法:
正确写法:setFilteredUsers((filteredUsers = filteredList));setFilteredUsers(filteredList);
修正后的完整函数组件代码
import React, { useState, useEffect } from "react"; import DataTable from "./DataTable"; import Nav from "./Nav"; import API from "../utils/API"; import "../styles/DataArea.css"; const DataArea = () => { const [users, setUsers] = useState([{}]); const [order, setOrder] = useState("descend"); const [filteredUsers, setFilteredUsers] = useState([{}]); const headings = [ { name: "Image", width: "10%" }, { name: "Name", width: "10%" }, { name: "Phone", width: "20%" }, { name: "Email", width: "20%" }, { name: "DOB", width: "10%" }, ]; const handleSort = (heading) => { const newOrder = order === "descend" ? "ascend" : "descend"; setOrder(newOrder); const compareFnc = (a, b) => { if (newOrder === "ascend") { // 处理缺失值 if (a[heading] === undefined) return 1; if (b[heading] === undefined) return -1; // 姓名按字符串排序 if (heading === "name") { return a[heading].first.localeCompare(b[heading].first); } // 其他字段按数值排序 return a[heading] - b[heading]; } else { // 处理缺失值 if (a[heading] === undefined) return 1; if (b[heading] === undefined) return -1; // 姓名按字符串排序 if (heading === "name") { return b[heading].first.localeCompare(a[heading].first); } // 其他字段按数值排序 return b[heading] - a[heading]; } }; const sortedUsers = [...filteredUsers].sort(compareFnc); setFilteredUsers(sortedUsers); }; const handleSearchChange = (event) => { const filter = event.target.value; const filteredList = users.filter((item) => { // 合并所有字段值,匹配搜索内容 const values = Object.values(item).join("").toLowerCase(); return values.includes(filter.toLowerCase()); }); setFilteredUsers(filteredList); }; useEffect(() => { API.getUsers().then((results) => { const userList = results.data.results; setUsers(userList); setFilteredUsers(userList); }); }, []); return ( <> <Nav handleSearchChange={handleSearchChange} /> <div className="data-area"> <DataTable headings={headings} users={filteredUsers} handleSort={handleSort} /> </div> </> ); }; export default DataArea;
内容的提问来源于stack exchange,提问作者Kevin Millhouse
相关产品推荐
相关产品推荐

