如何在 React 中搜索 运行 后显示 "no records found"
How to display "no records found" after running a search in React
我一直在尝试在 运行 搜索工人姓名后添加“未找到记录”消息。但我没有成功。我要么收到 20 条“未找到记录”消息,要么根本 none。我不确定自己做错了什么,但过去 4 个小时我一直在尝试各种方法和解决方法。
我知道这实现起来应该很简单,但是一直很难。
这是我在 codesandbox 上的代码的 link:https://codesandbox.io/s/fe-hatc-ass-search-n62kw?file=/src/App.js
任何见解都会有所帮助....
我试过的东西是,if else 语句,逻辑运算符……等……
查看您的代码,问题在于您在每个单独的 <Order>
组件中进行过滤。过滤应该在父 Orders
组件中完成,如果找到匹配,你应该只渲染一个 <Order>
组件。
目前,您的 <Order>
组件正在呈现,即使没有匹配项也是如此。
您可以在 Orders.js 中添加一个状态来计算呈现的项目数。但是,由于每个 Worker 都依赖于 api 调用,因此您需要让响应(getWorker,在 Workers.js 中)等待响应才能进行计数。每次输入值改变时,您应该将计数器重置为 0。
https://codesandbox.io/s/fe-hatc-ass-search-forked-elyjz?file=/src/Worker.js:267-276
此外,作为注释,将 运行 中的函数放在 useEffect 中更安全,在 useEffect 内部,这样更容易查看是否缺少依赖项。
在我看来,您首先需要考虑的是您需要什么数据以及何时需要。要像您希望的那样不显示任何结果,您将需要在进行过滤的组件中使用工作人员姓名。所以你会在订单组件中需要它。我会将工作人员数据与订单数据合并,然后您就可以在之后过滤和操作数据。这也会阻止你在每次有人更改输入时发出 api 请求,你需要做的就是过滤已经获取的数据。然后您可以检查数组长度,如果它大于 0 则可以显示结果,否则显示无结果语句。
所以像下面这样:
订单组件
import React, { useEffect, useState } from "react";
import "./Orders.css";
import Order from "./Worker";
import axios from "axios";
const Orders = () => {
const [orders, setOrders] = useState([]);
const [results, setResults] = useState([]);
const [searchedWorker, setSearchedWorker] = useState("");
const getOrders = async () => {
const workOrders = await axios.get(
"https://api.hatchways.io/assessment/work_orders"
);
const mappedOrders = await Promise.all(workOrders.data.orders.map(async order => {
const worker = await axios.get(
`https://api.hatchways.io/assessment/workers/${order.workerId}`
);
return {...order, worker: worker.data.worker}
}))
setOrders(mappedOrders);
};
useEffect(() => {
getOrders();
}, []);
useEffect(() => {
const filtered = orders.filter(order => order.worker.name.toLowerCase().includes(searchedWorker));
setResults(filtered)
}, [searchedWorker, orders])
return (
<div>
<h1>Orders</h1>
<input
type="text"
name="workerName"
id="workerName"
placeholder="Filter by workername..."
value={searchedWorker} //property specifies the value associated with the input
onChange={(e) => setSearchedWorker(e.target.value.toLowerCase())}
//onChange captures the entered values and stores it inside our state hooks
//then we pass the searched values as props into the component
/>
<p>Results: {results.length}</p>
{results.length > 0 ? results.map((order) => (
<Order key={order.id} lemon={order} />
)) : <p>No results found</p> }
</div>
);
};
//(if this part is true) && (this part will execute)
//is short for: if(condition){(this part will execute)}
export default Orders;
然后你可以简化你的单一订单组件
import React from "react";
const Order = ({ lemon }) => {
return (
<div>
<div className="order">
<p>Work order {lemon.id}</p>
<p>{lemon.description}</p>
<img src={`${lemon.worker.image}`} alt="worker" />
<p>{lemon.worker.name}</p>
<p>{lemon.worker.company}</p>
<p>{lemon.worker.email}</p>
<p>{new Date(lemon.deadline).toLocaleString()}</p>
</div>
</
div>
);
};
export default Order;
我一直在尝试在 运行 搜索工人姓名后添加“未找到记录”消息。但我没有成功。我要么收到 20 条“未找到记录”消息,要么根本 none。我不确定自己做错了什么,但过去 4 个小时我一直在尝试各种方法和解决方法。
我知道这实现起来应该很简单,但是一直很难。 这是我在 codesandbox 上的代码的 link:https://codesandbox.io/s/fe-hatc-ass-search-n62kw?file=/src/App.js
任何见解都会有所帮助.... 我试过的东西是,if else 语句,逻辑运算符……等……
查看您的代码,问题在于您在每个单独的 <Order>
组件中进行过滤。过滤应该在父 Orders
组件中完成,如果找到匹配,你应该只渲染一个 <Order>
组件。
目前,您的 <Order>
组件正在呈现,即使没有匹配项也是如此。
您可以在 Orders.js 中添加一个状态来计算呈现的项目数。但是,由于每个 Worker 都依赖于 api 调用,因此您需要让响应(getWorker,在 Workers.js 中)等待响应才能进行计数。每次输入值改变时,您应该将计数器重置为 0。
https://codesandbox.io/s/fe-hatc-ass-search-forked-elyjz?file=/src/Worker.js:267-276
此外,作为注释,将 运行 中的函数放在 useEffect 中更安全,在 useEffect 内部,这样更容易查看是否缺少依赖项。
在我看来,您首先需要考虑的是您需要什么数据以及何时需要。要像您希望的那样不显示任何结果,您将需要在进行过滤的组件中使用工作人员姓名。所以你会在订单组件中需要它。我会将工作人员数据与订单数据合并,然后您就可以在之后过滤和操作数据。这也会阻止你在每次有人更改输入时发出 api 请求,你需要做的就是过滤已经获取的数据。然后您可以检查数组长度,如果它大于 0 则可以显示结果,否则显示无结果语句。
所以像下面这样:
订单组件
import React, { useEffect, useState } from "react";
import "./Orders.css";
import Order from "./Worker";
import axios from "axios";
const Orders = () => {
const [orders, setOrders] = useState([]);
const [results, setResults] = useState([]);
const [searchedWorker, setSearchedWorker] = useState("");
const getOrders = async () => {
const workOrders = await axios.get(
"https://api.hatchways.io/assessment/work_orders"
);
const mappedOrders = await Promise.all(workOrders.data.orders.map(async order => {
const worker = await axios.get(
`https://api.hatchways.io/assessment/workers/${order.workerId}`
);
return {...order, worker: worker.data.worker}
}))
setOrders(mappedOrders);
};
useEffect(() => {
getOrders();
}, []);
useEffect(() => {
const filtered = orders.filter(order => order.worker.name.toLowerCase().includes(searchedWorker));
setResults(filtered)
}, [searchedWorker, orders])
return (
<div>
<h1>Orders</h1>
<input
type="text"
name="workerName"
id="workerName"
placeholder="Filter by workername..."
value={searchedWorker} //property specifies the value associated with the input
onChange={(e) => setSearchedWorker(e.target.value.toLowerCase())}
//onChange captures the entered values and stores it inside our state hooks
//then we pass the searched values as props into the component
/>
<p>Results: {results.length}</p>
{results.length > 0 ? results.map((order) => (
<Order key={order.id} lemon={order} />
)) : <p>No results found</p> }
</div>
);
};
//(if this part is true) && (this part will execute)
//is short for: if(condition){(this part will execute)}
export default Orders;
然后你可以简化你的单一订单组件
import React from "react";
const Order = ({ lemon }) => {
return (
<div>
<div className="order">
<p>Work order {lemon.id}</p>
<p>{lemon.description}</p>
<img src={`${lemon.worker.image}`} alt="worker" />
<p>{lemon.worker.name}</p>
<p>{lemon.worker.company}</p>
<p>{lemon.worker.email}</p>
<p>{new Date(lemon.deadline).toLocaleString()}</p>
</div>
</
div>
);
};
export default Order;