javascript - 将类组件转换为功能组件 TypeError: users.filter is not a function
问题描述
制作员工目录,我正在尝试将类组件转换为功能组件。导航、搜索和表格将呈现,但对 api 的调用不起作用。获得一个
TypeError: users.filter is not a function
Here 是工作的类组件和正在进行的功能组件。我无法弄清楚有什么不同。
import React, { Component } from "react";
import DataTable from "./DataTable";
import Nav from "./Nav";
import API from "../utils/API";
import "../styles/DataArea.css";
export default class DataArea extends Component {
state = {
users: [{}],
order: "descend",
filteredUsers: [{}]
}
headings = [
{ name: "Image", width: "10%" },
{ name: "Name", width: "10%" },
{ name: "Phone", width: "20%" },
{ name: "Email", width: "20%" },
{ name: "DOB", width: "10%" }
]
handleSort = heading => {
if (this.state.order === "descend") {
this.setState({
order: "ascend"
})
} else {
this.setState({
order: "descend"
})
}
const compareFnc = (a, b) => {
if (this.state.order === "ascend") {
// account for missing values
if (a[heading] === undefined) {
return 1;
} else if (b[heading] === undefined) {
return -1;
}
// numerically
else if (heading === "name") {
return a[heading].first.localeCompare(b[heading].first);
} else {
return a[heading] - b[heading];
}
} else {
// account for missing values
if (a[heading] === undefined) {
return 1;
} else if (b[heading] === undefined) {
return -1;
}
// numerically
else if (heading === "name") {
return b[heading].first.localeCompare(a[heading].first);
} else {
return b[heading] - a[heading];
}
}
}
const sortedUsers = this.state.filteredUsers.sort(compareFnc);
this.setState({ filteredUsers: sortedUsers });
}
handleSearchChange = event => {
console.log(event.target.value);
const filter = event.target.value;
const filteredList = this.state.users.filter(item => {
// merge data together, then see if user input is anywhere inside
let values = Object.values(item)
.join("")
.toLowerCase();
return values.indexOf(filter.toLowerCase()) !== -1;
});
this.setState({ filteredUsers: filteredList });
}
componentDidMount() {
API.getUsers().then(results => {
this.setState({
users: results.data.results,
filteredUsers: results.data.results
});
});
}
render() {
return (
<>
<Nav handleSearchChange={this.handleSearchChange} />
<div className="data-area">
<DataTable
headings={this.headings}
users={this.state.filteredUsers}
handleSort={this.handleSort}
/>
</div>
</>
);
}
}
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) => {
if (order === "descend") {
setOrder((order = "ascend"));
} else {
setOrder((order = "descend"));
}
const compareFnc = (a, b) => {
if (order === "ascend") {
// account for missing values
if (a[heading] === undefined) {
return 1;
} else if (b[heading] === undefined) {
return -1;
}
// numerically
else if (heading === "name") {
return a[heading].first.localeCompare(b[heading].first);
} else {
return a[heading] - b[heading];
}
} else {
// account for missing values
if (a[heading] === undefined) {
return 1;
} else if (b[heading] === undefined) {
return -1;
}
// numerically
else if (heading === "name") {
return b[heading].first.localeCompare(a[heading].first);
} else {
return b[heading] - a[heading];
}
}
};
const sortedUsers = filteredUsers.sort(compareFnc);
setFilteredUsers({ filteredUsers: sortedUsers });
};
let handleSearchChange = (event) => {
console.log(event.target.value);
const filtered = event.target.value;
const filteredList = users.filter((item) => {
// merge data together, then see if user input is anywhere inside
let values = Object.values(item).join("").toLowerCase();
return values.indexOf(filtered.toLowerCase()) !== -1;
});
setFilteredUsers((filteredUsers = filteredList));
};
useEffect(() => {
API.getUsers().then((results) => {
setUsers({
users: results.data.results,
filteredUsers: results.data.results,
});
});
}, []);
return (
<>
<Nav handleSearchChange={handleSearchChange} />
<div className="data-area">
<DataTable
headings={headings}
users={filteredUsers}
handleSort={handleSort}
/>
</div>
</>
);
};
export default DataArea;
解决方案
问题出在你的useEffect
钩子上,你把它们都硬users
塞进filteredUsers
你的users
状态。
useEffect(() => {
API.getUsers().then((results) => {
setUsers({
users: results.data.results,
filteredUsers: results.data.results,
});
});
}, []);
它应该是
useEffect(() => {
API.getUsers().then((results) => {
setUsers(results.data.results);
setFilteredUsers(results.data.results),
});
}, []);
您想要填充users
状态和单独的filteredUsers
状态。
设置排序顺序的问题,您正在改变order
状态:
if (order === "descend") {
setOrder((order = "ascend")); // <-- mutates
} else {
setOrder((order = "descend")); // <-- mutates
}
您可以简单地在两者之间切换:
setOrder(order => order === 'ascend' ? 'descend' : 'ascend');
另一个问题是在您的handleSort
功能结束时:
const sortedUsers = filteredUsers.sort(compareFnc);
setFilteredUsers({ filteredUsers: sortedUsers });
这将嵌套filteredUsers数组,并就地改变数组,它可能应该使用功能状态更新来从以前的状态更新,使用array.slice进行复制,然后调用sort。
setFilteredUsers(filteredUsers => filteredUsers.slice().sort(compareFnc));
推荐阅读
- r - ggplot 直方图在布尔值上拆分
- excel - 从 VBA Excel for Mac 和 Windows 在 HTTP Post 中发送数据
- r - 意外的聚类错误(围绕介质进行分区)
- python - 在股票页面中抓取雅虎财经对话
- python - _Scraping_ 使用来自论坛的 Beautiful Soup - 如何刮掉重复多次的表?
- javascript - 尝试在 React Native 上运行 Jest,出现多个错误,最后一个是:TypeError: Cannot read property 'createAnimatedComponent' of undefined
- powershell - 无法在 PoweSshell 中显示 export-csv
- sqlite - MS Access 和 qGIS .gpkg 数据之间的 ODBC 链接?
- c# - 如果不满足特定时间范围,如何启用或禁用组合框中的值
- node.js - 使用前端授权从nodejs后端调用google drive api