javascript - 我的搜索栏 React 没有返回任何结果
问题描述
我在我的 React-Firebase 仪表板中添加了一个搜索栏。结果,当我在搜索栏中输入文本时,搜索栏会显示存储在 Cloud Firestore 中的客户端表,即使它返回一个空表表中存在单词。
PS:两个结果都显示在下面的屏幕截图中
客户.js
import React, { Fragment, useState } from "react";
import { Avatar } from '@material-ui/core';
import PageTitle from "../../../../layouts/PageTitle";
import { Dropdown, Table } from "react-bootstrap";
import { fire } from "../../../../../fire";
import { firestore } from "../../../../../fire";
import { collection, query, where } from "../../../../../fire";
import App from "../../../../../App";
export default class Recipe extends React.Component {
state = {
searchTerm : "",
Users: []
}
constructor(props){
super(props);
}
searchByTerm = (value) => {
this.setState({searchTerm : value});
}
componentDidMount() {
firestore.collection("Users").get().then((querySnapshot) => {
let User = []
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data().lastn}`);
User.push({
id : doc.id,
data: doc.data()})
});
this.setState({Users : User})
});
}
delete = (id) => {
console.log(id)
firestore.collection("Users").doc(id).delete().then(() => {
console.log("Document successfully deleted!");
this.props.history.push("#")
}).catch((error) => {console.error("Error removing document: ",
error);
});
}
render() {
return (
<Fragment>
<div className="col-12">
<div className="card">
<div className="card-header">
<div className="input-group search-area d-lg-inline-flex d-none mr-
5">
<input
type="text"
className="form-control"
placeholder="Search here"
onChange ={(e) => {
this.searchByTerm(e.target.value);
}}
/>
<div className="input-group-append">
<span className="input-group-text"
>
<svg
width={20}
height={20}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M23.7871 22.7761L17.9548 16.9437C19.5193 15.145 20.4665 12.7982 20.4665 10.2333C20.4665 4.58714 15.8741 0 10.2333 0C4.58714 0 0 4.59246 0 10.2333C0 15.8741 4.59246 20.4665 10.2333 20.4665C12.7982 20.4665 15.145 19.5193 16.9437 17.9548L22.7761 23.7871C22.9144 23.9255 23.1007 24 23.2816 24C23.4625 24 23.6488 23.9308 23.7871 23.7871C24.0639 23.5104 24.0639 23.0528 23.7871 22.7761ZM1.43149 10.2333C1.43149 5.38004 5.38004 1.43681 10.2279 1.43681C15.0812 1.43681 19.0244 5.38537 19.0244 10.2333C19.0244 15.0812 15.0812 19.035 10.2279 19.035C5.38004 19.035 1.43149 15.0865 1.43149 10.2333Z"
fill="#A4A4A4"
/>
</svg>
</span>
</div> </div>
<h4 className="card-title">Customer List </h4>
</div>
<div className="card-body">
<Table responsive className="w-100">
<div id="example_wrapper" className="dataTables_wrapper">
<table id="example" className="display w-100 dataTable">
<thead>
<tr role="row">
<th>Avatar</th>
<th>Email</th>
<th>Firstname</th>
<th>Lastname</th>
<th>PhoneNumber</th>
{/* <th className="pl-5 width200">
Billing Address
</th> */}
<th>Action</th>
</tr>
</thead>
<tbody>
{this.state.Users.filter( (val) =>{
const { email = "", firstname = "" } = val;
// console.log(this.state.searchTerm);
if (this.state.searchTerm === "") {
return val;
} else if (
email.toLowerCase().includes(this.state.searchTerm.toLowerCase()) ||
firstname.toLowerCase().includes(this.state.searchTerm.toLowerCase())
) {
return val;
}
}).map(data => {
return (
<tr>
<td> <Avatar className ="rounded-circle img-fluid" src={data.data.avatar}/> </td>
<td>{data.data.email}</td>
<td>{data.data.firstname}</td>
<td>{data.data.datalastname}</td>
<td>{data.data.phonenumber}</td>
<td>
<div
className="btn btn-danger shadow btn-xs sharp" onClick ={this.delete.bind(this, data.id)}
>
<i className="fa fa-trash"></i> </div></td>
</tr>
);
})}
</tbody>
</table>
</div>
</Table>
</div>
</div>
</div>
</Fragment>
);
};
};
解决方案
Array.prototype.filter
回调应该返回一个布尔值,而不是被迭代的元素。
这就是我建议重写您的过滤器函数的方式:如果没有搜索词(即 false),则返回 true 以指示应返回所有迭代过的元素,否则返回比较结果。
const { Users, searchTerm } = this.state;
const term = this.state.searchTerm.toLowerCase();
...
Users.filter((val) => {
const { data: { email = "", firstname = "" } = {} } = val;
if (term) {
return (
email.toLowerCase().includes(term) ||
firstname.toLowerCase().includes(term)
);
}
return true;
})
稍微简洁一点的版本可以写成如下:
const { Users, searchTerm } = this.state;
const term = this.state.searchTerm.toLowerCase();
...
Users.filter(({ data: { email = "", firstname = "" } = {} }) =>
term ? email.concat(firstname).toLowerCase().includes(term) : true
)
更新
在您声明您实施了我的建议但它仍然无法正常工作后,我仔细查看了您正在呈现的内容,并注意到在.map
回调中您从每个元素的属性中引用了每个字段( email
,firstname
等...) 。data
由于似乎您可以在未应用过滤器时呈现数据,因此我假设此结构是正确的。因此,回调还.filter
需要从属性中引用嵌套的字段属性。我已经更新了上面的代码片段。data
推荐阅读
- javascript - 使用 innerHTML 创建的 HTML 音频元素在播放时会引发 DOMException
- java - Intelliji 调试不适用于 testng maven
- video - 为什么使用 youtube-dl 设置代理参数时无法下载视频标题?
- javascript - 在 SCEditor 中将列表项标签设置为 [*]x 而不是 [li]x[/li] 以实现 vBulletin 兼容性
- r - 如何使用 position_nudge 将 x 轴标签与 ggplot2 中的条形中心对齐
- c# - UDP发送任务在队列中等待消息会耗尽CPU
- ios - iOS - NSISEngine 崩溃
- json - 如何从 JSON 文件中获取特定数据?
- android - 带有 Gridlayoutmanager 的 Recyclerview 的 Android Firebase 分页
- javascript - 无法使用 Google Apps 脚本发送带附件的电子邮件