Javascript 在React中筛选时,数组项仅出现一次
在这个React代码中,我试图从列表中获取与setManName函数中的文本输入类型匹配的所有项目(setModeName函数中也有一个)。它可以工作,但当我删除文本输入并重新开始时,这些项目将消失,不再出现,除非我重新加载页面并重新开始,否则不会显示在屏幕上。我使用的是inludes()方法,效果很好,但一旦我删除一个字母或整个单词并重新开始,它就不起作用了。这里有什么问题?我应该使用不同的方法吗?像是另一种效果还是什么Javascript 在React中筛选时,数组项仅出现一次,javascript,arrays,reactjs,Javascript,Arrays,Reactjs,在这个React代码中,我试图从列表中获取与setManName函数中的文本输入类型匹配的所有项目(setModeName函数中也有一个)。它可以工作,但当我删除文本输入并重新开始时,这些项目将消失,不再出现,除非我重新加载页面并重新开始,否则不会显示在屏幕上。我使用的是inludes()方法,效果很好,但一旦我删除一个字母或整个单词并重新开始,它就不起作用了。这里有什么问题?我应该使用不同的方法吗?像是另一种效果还是什么 import React, { useState, useEffect
import React, { useState, useEffect } from "react";
import "./style.css";
export default function App() {
const [items, setItems] = useState([])
const [openFilterCt, setOpenFilterCt] = useState(false)
const [term1, setTerm1] = useState()
const [term2, setTerm2] = useState()
useEffect(() => {
fetch("https://private-anon-af560a53c6-carsapi1.apiary-mock.com/cars")
.then(res => res.json())
.then(data => {
setItems(data)
})
}, [])
function setManName(e) {
setTerm1(e.target.value);
let u = items.filter(item => {
**return item.make.includes(e.target.value)**
})
setItems(u)
}
function setModName(e) {
setTerm2(e.target.value);
let u = items.filter(item => {
**return item.model.includes(e.target.value)**
})
setItems(u)
}
function hi() {
setOpenFilterCt(!openFilterCt)
}
return (
<div>
<h1>React Search & Filter</h1>
<div>
<h3 onClick={hi}>Filter</h3>
<div className={openFilterCt ? "show" : "hide"}>
<label>
Name of manufacturer: <input type="text" value={term1} onChange={setManName} />
</label>
<br />
<label>
Name of model: <input type="text" value={term2} onChange={setModName} />
</label>
</div>
</div>
{items.slice(0, 50).map((a, index) => {
return (
<div key={index} style={{border: "1px solid black", margin: "10px", padding: "5px"}}>
<p>Manufacturer: {a.make[0].toUpperCase() + a.make.slice(1)}</p>
<p>Model: {a.model}</p>
</div>
)
})}
</div>
);
}
从“React”导入React,{useState,useffect};
导入“/style.css”;
导出默认函数App(){
const[items,setItems]=useState([])
const[openFilterCt,setOpenFilterCt]=useState(false)
const[term1,setTerm1]=useState()
const[term2,setTerm2]=useState()
useffect(()=>{
取回(“https://private-anon-af560a53c6-carsapi1.apiary-mock.com/cars")
.then(res=>res.json())
。然后(数据=>{
设置项目(数据)
})
}, [])
函数setManName(e){
setTerm1(即目标值);
设u=items.filter(item=>{
**退货项目.制造.包括(如目标值)**
})
集合项目(u)
}
函数setModName(e){
setTerm2(即目标值);
设u=items.filter(item=>{
**返回项.model.includes(例如target.value)**
})
集合项目(u)
}
函数hi(){
setOpenFilterCt(!openFilterCt)
}
返回(
反应搜索和过滤
滤器
制造商名称:
型号名称:
{items.slice(0,50).map((a,index)=>{
返回(
制造商:{a.make[0].toUpperCase()+a.make.slice(1)}
模型:{a.Model}
)
})}
);
}
我刚刚为您的型号搜索修复了它,您可以对制造商搜索执行相同的操作。也许有更好的方法,但这是我解决的问题
您需要做的是保留原始列表.filter()
实际上更改了原始列表,当响应为空时,原始数据将消失。所以我只是保留了旧数据
const [orItem, setOrItems] = useState([]);
const prevList = orItem;
function setModName(e) {
setTerm2(e.target.value);
let u = prevList.filter((item) => {
return item.model.includes(e.target.value);
});
setItems(u);
}
您可以在此处看到用于模型搜索的代码:
您正在覆盖items对象,因此,即使删除了字符,也不会显示未在搜索中的任何项目。此解决方案将动态筛选项,而不是将其从阵列中删除 此外,您应该为
term1
和term2
状态提供默认值。如果没有默认值,输入将从非受控输入切换到受控输入,这是React中不鼓励的做法
看
import React,{useState,useffect}来自“React”;
导入“/style.css”;
导出默认函数App(){
const[items,setItems]=useState([]);
const[openFilterCt,setOpenFilterCt]=useState(false);
const[term1,setTerm1]=useState(“”);
const[term2,setTerm2]=useState(“”);
useffect(()=>{
取回(“https://private-anon-af560a53c6-carsapi1.apiary-mock.com/cars")
.然后((res)=>res.json())
。然后((数据)=>{
设置项目(数据);
});
}, []);
函数setManName(e){
setTerm1(即目标值);
}
函数setModName(e){
setTerm2(即目标值);
}
功能过滤器项(项目){
如果(term1&&!item.make.includes(term1))返回false;
if(term2&&!item.model.includes(term2))返回false;
返回true;
}
函数hi(){
setOpenFilterCt(!openFilterCt);
}
返回(
反应搜索和过滤
滤器
制造商名称:{“}
模型名称:{“”}
{项目
.过滤器(过滤器)
.切片(0,50)
.map((a,索引)=>{
返回(
制造商:{a.make[0].toUpperCase()+a.make.slice(1)}
模型:{a.Model}
);
})}
);
}
首先,您不应该修改原始数组项
。您需要创建另一个(另一个状态变量)filteredItems
,以便可以重置为原始状态,而且我相信这里还有另一个错误item.model.includes(e.target.value)
,如果文本为空,它将始终返回false
function setManName(e) {
setTerm1(e.target.value);
if(e.target.value){
let u = items.filter(item => {
return item.make.includes(e.target.value)
})
setFilteredItems(u)
}else{
setItems(items)
}
}
另外,useffect
hook应该是这样的:
useEffect(() => {
fetch("https://private-anon-af560a53c6-carsapi1.apiary-mock.com/cars")
.then(res => res.json())
.then(data => {
setItems(data)
setFilteredItems(data)
})
}, [])
并确保
map
覆盖filteredItems
这里的问题是您正在重置从给定URL接收的值。您应该维护一个单独的可见性列表,您可以使用方法1。如下所示。这是我在不修改大量代码的情况下所能做的最好的事情,但是这通常是对状态的过度/错误使用。记住React之所以被称为React,是因为它在状态改变时具有惊人的反应能力。
Approach 2实现了这一点,您可以灵活地使用过滤器,并根据需要对其进行更改。你的搜索行为
// Approach 1
import React, { useState, useEffect } from "react";
// import "./style.css";
export default function App() {
const [items, setItems] = useState([]);
const [visibleItems, setVisibleItems] = useState([]);
const [openFilterCt, setOpenFilterCt] = useState(false)
const [term1, setTerm1] = useState()
const [term2, setTerm2] = useState()
useEffect(() => {
fetch("https://private-anon-af560a53c6-carsapi1.apiary-mock.com/cars")
.then(res => res.json())
.then(data => {
setItems(data);
setVisibleItems(data);
})
}, [])
function setManName(e) {
// setTerm1(e.target.value);
let u = items.filter(item => {
if(e.target.value){
return item.make.includes(e.target.value)
}
return true;
})
setVisibleItems(u)
}
function setModName(e) {
// setTerm2(e.target.value);
let u = items.filter(item => {
return item.model.includes(e.target.value)
})
setVisibleItems(u)
}
function hi() {
setOpenFilterCt(!openFilterCt)
}
return (
<div>
<h1>React Search & Filter</h1>
<div>
<h3 onClick={hi}>Filter</h3>
<div className={openFilterCt ? "show" : "hide"}>
<label>
Name of manufacturer: <input type="text" value={term1} onChange={setManName} />
</label>
<br />
<label>
Name of model: <input type="text" value={term2} onChange={setModName} />
</label>
</div>
</div>
{visibleItems.slice(0, 50).map((a, index) => {
return (
<div key={index} style={{border: "1px solid black", margin: "10px", padding: "5px"}}>
<p>Manufacturer: {a.make[0].toUpperCase() + a.make.slice(1)}</p>
<p>Model: {a.model}</p>
</div>
)
})}
</div>
);
}
//方法1
从“React”导入React,{useState,useffect};
//导入“/style.css”;
导出默认函数App(){
const[items,setItems]=useState([]);
const[visibleItems,setVisibleItems]=useState([]);
const[openFilterCt,setOpenFilterCt]=useState(false)
const[term1,setTerm1]=useState()
const[term2,setTerm2]=useState()
useffect(()=>{
取回(“https://private-anon-af560a53c6-carsapi1.apiary-mock.com/cars")
.then(res=>res.json())
。然后(数据=>{
设置项目(数据);
设置可见项(数据);
})
}, [])
函数setManName(e){
// Approach 1
import React, { useState, useEffect } from "react";
// import "./style.css";
export default function App() {
const [items, setItems] = useState([]);
const [visibleItems, setVisibleItems] = useState([]);
const [openFilterCt, setOpenFilterCt] = useState(false)
const [term1, setTerm1] = useState()
const [term2, setTerm2] = useState()
useEffect(() => {
fetch("https://private-anon-af560a53c6-carsapi1.apiary-mock.com/cars")
.then(res => res.json())
.then(data => {
setItems(data);
setVisibleItems(data);
})
}, [])
function setManName(e) {
// setTerm1(e.target.value);
let u = items.filter(item => {
if(e.target.value){
return item.make.includes(e.target.value)
}
return true;
})
setVisibleItems(u)
}
function setModName(e) {
// setTerm2(e.target.value);
let u = items.filter(item => {
return item.model.includes(e.target.value)
})
setVisibleItems(u)
}
function hi() {
setOpenFilterCt(!openFilterCt)
}
return (
<div>
<h1>React Search & Filter</h1>
<div>
<h3 onClick={hi}>Filter</h3>
<div className={openFilterCt ? "show" : "hide"}>
<label>
Name of manufacturer: <input type="text" value={term1} onChange={setManName} />
</label>
<br />
<label>
Name of model: <input type="text" value={term2} onChange={setModName} />
</label>
</div>
</div>
{visibleItems.slice(0, 50).map((a, index) => {
return (
<div key={index} style={{border: "1px solid black", margin: "10px", padding: "5px"}}>
<p>Manufacturer: {a.make[0].toUpperCase() + a.make.slice(1)}</p>
<p>Model: {a.model}</p>
</div>
)
})}
</div>
);
}
// Approach2
import React, { useState, useEffect } from "react";
// import "./style.css";
export default function App() {
const [items, setItems] = useState([]);
const [openFilterCt, setOpenFilterCt] = useState(false);
const [term1, setTerm1] = useState("");
const [term2, setTerm2] = useState("");
useEffect(() => {
fetch("https://private-anon-af560a53c6-carsapi1.apiary-mock.com/cars")
.then((res) => res.json())
.then((data) => {
setItems(data);
});
}, []);
function setManName(e) {
setTerm1(e.target.value);
}
function setModName(e) {
setTerm2(e.target.value);
}
function hi() {
setOpenFilterCt(!openFilterCt);
}
return (
<div>
<h1>React Search & Filter</h1>
<div>
<h3 onClick={hi}>Filter</h3>
<div className={openFilterCt ? "show" : "hide"}>
<label>
Name of manufacturer:{" "}
<input type="text" value={term1} onChange={setManName} />
</label>
<br />
<label>
Name of model:{" "}
<input type="text" value={term2} onChange={setModName} />
</label>
</div>
</div>
{items
.filter((item) => {
return item.make.includes(term1) && item.model.includes(term2);
})
.slice(0, 50)
.map((a, index) => {
return (
<div
key={index}
style={{
border: "1px solid black",
margin: "10px",
padding: "5px"
}}
>
<p>Manufacturer: {a.make[0].toUpperCase() + a.make.slice(1)}</p>
<p>Model: {a.model}</p>
</div>
);
})}
</div>
);
}