在 React Js 中使用多个复选框过滤列表
Filter The List Using Multiple CheckBoxes in React Js
大家好,我正在尝试根据条件过滤复选框 onClick 的对象数组列表,但是我在 handle 方法中的其他条件返回给我一个相同的数组,状态没有改变,所以我想要默认列表,当我尝试取消选中所有列表时删除筛选列表。
import React from "react";
import "./Search.css";
class Search extends React.Component {
constructor() {
super();
this.state = {
searchLists: [
{
id: 1,
type: "All",
name: "Akash",
location: "bangalore",
experience: 1
},
{
id: 2,
type: "FullTime",
name: "feroz",
location: "mumbai",
experience: 3
},
{
id: 3,
type: "PartTime",
name: "Farheen",
location: "agra",
experience: 5
},
{
id: 4,
type: "Freelancer",
name: "Raju",
location: "chennai",
experience: 6
},
{
id: 5,
type: "All",
name: "Asif",
location: "vegas",
experience: 7
}
],
checked: false
};
}
handleAll = () => {
console.log("i clicked");
if (this.state.checked === false) {
const filteredAll = this.state.searchLists.filter(
item => item.type === "All"
);
console.log(filteredAll);
this.setState({ searchLists: filteredAll, checked: true });
} else {
setTimeout(() => {
this.setState({
searchLists: this.state.searchLists,
checked: false
});
}, 10000);
}
};
handleFullTime = () => {
if (this.state.checked === false) {
const filteredFullTime = this.state.searchLists.filter(
item => item.type === "FullTime"
);
console.log(filteredFullTime);
this.setState({ searchLists: filteredFullTime, checked: true });
} else {
setTimeout(() => {
this.setState({
searchLists: this.state.searchLists,
checked: false
});
}, 10000);
}
};
handlePartTime = () => {
if (this.state.checked === false) {
const filteredPartTime = this.state.searchLists.filter(
item => item.type === "PartTime"
);
console.log(filteredPartTime);
this.setState({ searchLists: filteredPartTime, checked: true });
} else {
setTimeout(() => {
this.setState({
searchLists: this.state.searchLists,
checked: false
});
}, 10000);
}
};
handleFreelancer = () => {
if (this.state.checked === false) {
const filteredFreelancer = this.state.searchLists.filter(
item => item.type === "Freelancer"
);
console.log(filteredFreelancer);
this.setState({ searchLists: filteredFreelancer, checked: true });
} else {
setTimeout(() => {
this.setState({
searchLists: this.state.searchLists,
checked: false
});
}, 10000);
}
};
render() {
console.log("rendered");
const mapped = this.state.searchLists.map(item => {
return (
<div key={item.id}>
<li>
{item.name}
{item.type}
</li>
</div>
);
});
return (
<div className="searchContainer">
<form>
<label htmlFor="myInput">All</label>
<input
id="myInput"
type="checkbox"
onClick={this.handleAll}
checked={this.state.checked}
/>
<label htmlFor="myInput">FullTime</label>
<input id="myInput" type="checkbox" onClick={this.handleFullTime} />
<label htmlFor="myInput">PartTime</label>
<input id="myInput" type="checkbox" onClick={this.handlePartTime} />
<label htmlFor="myInput">Freelancer</label>
<input id="myInput" type="checkbox" onClick={this.handleFreelancer} />
</form>
<ul style={{ marginLeft: "70px" }}>{mapped}</ul>
</div>
);
}
}
export default Search;
这是我的代码 link https://codesandbox.io/s/eloquent-brattain-orv76?file=/src/Search.js
不要用过滤后的结果覆盖您的州。截至目前,每次单击复选框时,您的搜索结果都会被替换为过滤数组。我会将过滤器 属性 添加到您的状态以保存当前选择的过滤器并在渲染期间使用它。
我建议重构您的代码以简化逻辑并消除超时,这会使您的应用看起来没有响应。
this.state ={
filter: 'none',
searchList: [...]
}
//unify all checkboxes to share logic, e holds information about event that triggered this function, we will add value to each checkbox for easy access
handleCheckbox = e => {
if (this.state.filter === e.target.value) this.setState({ filter: "none" });
else this.setState({ filter: e.target.value, checked: true });
};
//mapped variable will handle filtering results, if `state.filter` matches `item.type` item will be rendered, also if filter is set to none, all items are rendered, this will not preserve multiple filters though,
const mapped = const mapped = this.state.searchLists.map(item => {
if (item.type === this.state.filter || this.state.filter === "none")
return (...)
//lastly change inputs to pass filters
<input
id="myInput"
value="PartTime"
type="checkbox"
onClick={this.handleCheckbox}
/>
检查这是否按预期工作:
https://codesandbox.io/s/vibrant-meadow-9k8u7?file=/src/Search.js:1968-2111
选中的状态无效。我们应该将它存储为一个数组,push/pop 来自它的 checked/unchecked 个项目。
https://codesandbox.io/s/upbeat-ramanujan-b2jui
import React from "react";
import "./Search.css";
class Search extends React.Component {
constructor() {
super();
this.state = {
filterList: [
{
id: 11,
name: "Part Time",
value: "PART_TIME"
},
{
id: 12,
name: "Full Time",
value: "FULL_TIME"
},
{
id: 13,
name: "Freelancer",
value: "FREELANCER"
}
],
searchLists: [
{
id: 1,
type: "PART_TIME",
name: "Akash",
location: "bangalore",
experience: 1
},
{
id: 2,
type: "PART_TIME",
name: "feroz",
location: "mumbai",
experience: 3
},
{
id: 3,
type: "FULL_TIME",
name: "Farheen",
location: "agra",
experience: 5
},
{
id: 4,
type: "FREELANCER",
name: "Raju",
location: "chennai",
experience: 6
},
{
id: 5,
type: "FULL_TIME",
name: "Asif",
location: "vegas",
experience: 7
}
],
activeFilter: []
};
}
onFilterChange(filter) {
const { filterList, activeFilter } = this.state;
if (filter === "ALL") {
if (activeFilter.length === filterList.length) {
this.setState({ activeFilter: [] });
} else {
this.setState({ activeFilter: filterList.map(filter => filter.value) });
}
} else {
if (activeFilter.includes(filter)) {
const filterIndex = activeFilter.indexOf(filter);
const newFilter = [...activeFilter];
newFilter.splice(filterIndex, 1);
this.setState({ activeFilter: newFilter });
} else {
this.setState({ activeFilter: [...activeFilter, filter] });
}
}
}
render() {
const { filterList, activeFilter } = this.state;
let filteredList;
if (
activeFilter.length === 0 ||
activeFilter.length === filterList.length
) {
filteredList = this.state.searchLists;
} else {
filteredList = this.state.searchLists.filter(item =>
this.state.activeFilter.includes(item.type)
);
}
return (
<div className="searchContainer">
<form>
<label htmlFor="myInput">All</label>
<input
id="myInput"
type="checkbox"
onClick={() => this.onFilterChange("ALL")}
checked={activeFilter.length === filterList.length}
/>
{this.state.filterList.map(filter => (
<React.Fragment>
<label htmlFor={filter.id}>{filter.name}</label>
<input
id={filter.id}
type="checkbox"
checked={activeFilter.includes(filter.value)}
onClick={() => this.onFilterChange(filter.value)}
/>
</React.Fragment>
))}
</form>
<ul style={{ marginLeft: "70px" }}>
{filteredList.map(item => (
<div key={item.id}>
<li>
{item.name} -- {item.type}
</li>
</div>
))}
</ul>
</div>
);
}
}
export default Search;
在这里,我为我的复选框项目使用了美食。以下代码片段给出了复选框过滤的逻辑。 handleCuisineChange
是包含逻辑的函数。 for
循环的长度是 8,因为我在这里选择的菜系数量(复选框项目的数量)是 8。用你的复选框数据替换这里的 cuisines
。应用此逻辑,您的复选框项目就可以进行过滤了。
在axios
里面我使用了自己的后端API和端口号。
handleCuisineChange=(cuisine_id)=>
{
const {cuisineArray}=this.state; //an empty array declared in constructor
if (cuisineArray.indexOf(cuisine_id) == -1)
{
cuisineArray.push(cuisine_id);
}
else
{
var index=cuisineArray.indexOf(cuisine_id);
cuisineArray.splice(index,1);
}
const {cuisineArray2}=this.state; //an empty array declared in constructor
let i=0;
for (i=0;i<8;i++)
{
if(cuisineArray[i]==undefined)
{
cuisineArray2[i]=cuisineArray[0];
}
else
{
cuisineArray2[i]=cuisineArray[i];
}
}
this.props.history.push(`/checking3?cuisine_id1=${cuisineArray2[0]}&cuisine_id2=${cuisineArray2[1]}&cuisine_id3=${cuisineArray2[2]}&cuisine_id4=${cuisineArray2[3]}&cuisine_id5=${cuisineArray2[4]}&cuisine_id6=${cuisineArray2[5]}&cuisine_id7=${cuisineArray2[6]}&cuisine_id8=${cuisineArray2[7]}`);
let filterObj={cuisine_id1:cuisineArray2[0],cuisine_id2:cuisineArray2[1],cuisine_id3:cuisineArray2[2],cuisine_id4:cuisineArray2[3],cuisine_id5:cuisineArray2[4],cuisine_id6:cuisineArray2[5],cuisine_id7:cuisineArray2[6],cuisine_id8:cuisineArray2[7]};
axios(
{
method:'POST',
url:`http://localhost:7000/getCuisine`,
headers:{'Content-Type':'application/json'},
data:filterObj
}
)
.then(res=>
{
this.setState({restaurants:res.data.restaurants});
})
.catch(err=>console.log(err))
}
render()
{
const {restaurants}=this.state;
return(
<div>
<input type="checkbox" name="cuisines" id={"1"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > North Indian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"2"} onChange={(event) => this.handleCuisineChange("2")} />
<span className="checkbox-items" > south indian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"3"} onChange={(event) => this.handleCuisineChange("3")} />
<span className="checkbox-items" > chinese </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"4"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > fast food </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"5"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Street food </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"6"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > American </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"7"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Italian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"8"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Mexican </span> <div style={{display: "block"}}> </div>
</div>
)
} //render end
大家好,我正在尝试根据条件过滤复选框 onClick 的对象数组列表,但是我在 handle 方法中的其他条件返回给我一个相同的数组,状态没有改变,所以我想要默认列表,当我尝试取消选中所有列表时删除筛选列表。
import React from "react";
import "./Search.css";
class Search extends React.Component {
constructor() {
super();
this.state = {
searchLists: [
{
id: 1,
type: "All",
name: "Akash",
location: "bangalore",
experience: 1
},
{
id: 2,
type: "FullTime",
name: "feroz",
location: "mumbai",
experience: 3
},
{
id: 3,
type: "PartTime",
name: "Farheen",
location: "agra",
experience: 5
},
{
id: 4,
type: "Freelancer",
name: "Raju",
location: "chennai",
experience: 6
},
{
id: 5,
type: "All",
name: "Asif",
location: "vegas",
experience: 7
}
],
checked: false
};
}
handleAll = () => {
console.log("i clicked");
if (this.state.checked === false) {
const filteredAll = this.state.searchLists.filter(
item => item.type === "All"
);
console.log(filteredAll);
this.setState({ searchLists: filteredAll, checked: true });
} else {
setTimeout(() => {
this.setState({
searchLists: this.state.searchLists,
checked: false
});
}, 10000);
}
};
handleFullTime = () => {
if (this.state.checked === false) {
const filteredFullTime = this.state.searchLists.filter(
item => item.type === "FullTime"
);
console.log(filteredFullTime);
this.setState({ searchLists: filteredFullTime, checked: true });
} else {
setTimeout(() => {
this.setState({
searchLists: this.state.searchLists,
checked: false
});
}, 10000);
}
};
handlePartTime = () => {
if (this.state.checked === false) {
const filteredPartTime = this.state.searchLists.filter(
item => item.type === "PartTime"
);
console.log(filteredPartTime);
this.setState({ searchLists: filteredPartTime, checked: true });
} else {
setTimeout(() => {
this.setState({
searchLists: this.state.searchLists,
checked: false
});
}, 10000);
}
};
handleFreelancer = () => {
if (this.state.checked === false) {
const filteredFreelancer = this.state.searchLists.filter(
item => item.type === "Freelancer"
);
console.log(filteredFreelancer);
this.setState({ searchLists: filteredFreelancer, checked: true });
} else {
setTimeout(() => {
this.setState({
searchLists: this.state.searchLists,
checked: false
});
}, 10000);
}
};
render() {
console.log("rendered");
const mapped = this.state.searchLists.map(item => {
return (
<div key={item.id}>
<li>
{item.name}
{item.type}
</li>
</div>
);
});
return (
<div className="searchContainer">
<form>
<label htmlFor="myInput">All</label>
<input
id="myInput"
type="checkbox"
onClick={this.handleAll}
checked={this.state.checked}
/>
<label htmlFor="myInput">FullTime</label>
<input id="myInput" type="checkbox" onClick={this.handleFullTime} />
<label htmlFor="myInput">PartTime</label>
<input id="myInput" type="checkbox" onClick={this.handlePartTime} />
<label htmlFor="myInput">Freelancer</label>
<input id="myInput" type="checkbox" onClick={this.handleFreelancer} />
</form>
<ul style={{ marginLeft: "70px" }}>{mapped}</ul>
</div>
);
}
}
export default Search;
这是我的代码 link https://codesandbox.io/s/eloquent-brattain-orv76?file=/src/Search.js
不要用过滤后的结果覆盖您的州。截至目前,每次单击复选框时,您的搜索结果都会被替换为过滤数组。我会将过滤器 属性 添加到您的状态以保存当前选择的过滤器并在渲染期间使用它。
我建议重构您的代码以简化逻辑并消除超时,这会使您的应用看起来没有响应。
this.state ={
filter: 'none',
searchList: [...]
}
//unify all checkboxes to share logic, e holds information about event that triggered this function, we will add value to each checkbox for easy access
handleCheckbox = e => {
if (this.state.filter === e.target.value) this.setState({ filter: "none" });
else this.setState({ filter: e.target.value, checked: true });
};
//mapped variable will handle filtering results, if `state.filter` matches `item.type` item will be rendered, also if filter is set to none, all items are rendered, this will not preserve multiple filters though,
const mapped = const mapped = this.state.searchLists.map(item => {
if (item.type === this.state.filter || this.state.filter === "none")
return (...)
//lastly change inputs to pass filters
<input
id="myInput"
value="PartTime"
type="checkbox"
onClick={this.handleCheckbox}
/>
检查这是否按预期工作: https://codesandbox.io/s/vibrant-meadow-9k8u7?file=/src/Search.js:1968-2111
选中的状态无效。我们应该将它存储为一个数组,push/pop 来自它的 checked/unchecked 个项目。
https://codesandbox.io/s/upbeat-ramanujan-b2jui
import React from "react";
import "./Search.css";
class Search extends React.Component {
constructor() {
super();
this.state = {
filterList: [
{
id: 11,
name: "Part Time",
value: "PART_TIME"
},
{
id: 12,
name: "Full Time",
value: "FULL_TIME"
},
{
id: 13,
name: "Freelancer",
value: "FREELANCER"
}
],
searchLists: [
{
id: 1,
type: "PART_TIME",
name: "Akash",
location: "bangalore",
experience: 1
},
{
id: 2,
type: "PART_TIME",
name: "feroz",
location: "mumbai",
experience: 3
},
{
id: 3,
type: "FULL_TIME",
name: "Farheen",
location: "agra",
experience: 5
},
{
id: 4,
type: "FREELANCER",
name: "Raju",
location: "chennai",
experience: 6
},
{
id: 5,
type: "FULL_TIME",
name: "Asif",
location: "vegas",
experience: 7
}
],
activeFilter: []
};
}
onFilterChange(filter) {
const { filterList, activeFilter } = this.state;
if (filter === "ALL") {
if (activeFilter.length === filterList.length) {
this.setState({ activeFilter: [] });
} else {
this.setState({ activeFilter: filterList.map(filter => filter.value) });
}
} else {
if (activeFilter.includes(filter)) {
const filterIndex = activeFilter.indexOf(filter);
const newFilter = [...activeFilter];
newFilter.splice(filterIndex, 1);
this.setState({ activeFilter: newFilter });
} else {
this.setState({ activeFilter: [...activeFilter, filter] });
}
}
}
render() {
const { filterList, activeFilter } = this.state;
let filteredList;
if (
activeFilter.length === 0 ||
activeFilter.length === filterList.length
) {
filteredList = this.state.searchLists;
} else {
filteredList = this.state.searchLists.filter(item =>
this.state.activeFilter.includes(item.type)
);
}
return (
<div className="searchContainer">
<form>
<label htmlFor="myInput">All</label>
<input
id="myInput"
type="checkbox"
onClick={() => this.onFilterChange("ALL")}
checked={activeFilter.length === filterList.length}
/>
{this.state.filterList.map(filter => (
<React.Fragment>
<label htmlFor={filter.id}>{filter.name}</label>
<input
id={filter.id}
type="checkbox"
checked={activeFilter.includes(filter.value)}
onClick={() => this.onFilterChange(filter.value)}
/>
</React.Fragment>
))}
</form>
<ul style={{ marginLeft: "70px" }}>
{filteredList.map(item => (
<div key={item.id}>
<li>
{item.name} -- {item.type}
</li>
</div>
))}
</ul>
</div>
);
}
}
export default Search;
在这里,我为我的复选框项目使用了美食。以下代码片段给出了复选框过滤的逻辑。 handleCuisineChange
是包含逻辑的函数。 for
循环的长度是 8,因为我在这里选择的菜系数量(复选框项目的数量)是 8。用你的复选框数据替换这里的 cuisines
。应用此逻辑,您的复选框项目就可以进行过滤了。
在axios
里面我使用了自己的后端API和端口号。
handleCuisineChange=(cuisine_id)=>
{
const {cuisineArray}=this.state; //an empty array declared in constructor
if (cuisineArray.indexOf(cuisine_id) == -1)
{
cuisineArray.push(cuisine_id);
}
else
{
var index=cuisineArray.indexOf(cuisine_id);
cuisineArray.splice(index,1);
}
const {cuisineArray2}=this.state; //an empty array declared in constructor
let i=0;
for (i=0;i<8;i++)
{
if(cuisineArray[i]==undefined)
{
cuisineArray2[i]=cuisineArray[0];
}
else
{
cuisineArray2[i]=cuisineArray[i];
}
}
this.props.history.push(`/checking3?cuisine_id1=${cuisineArray2[0]}&cuisine_id2=${cuisineArray2[1]}&cuisine_id3=${cuisineArray2[2]}&cuisine_id4=${cuisineArray2[3]}&cuisine_id5=${cuisineArray2[4]}&cuisine_id6=${cuisineArray2[5]}&cuisine_id7=${cuisineArray2[6]}&cuisine_id8=${cuisineArray2[7]}`);
let filterObj={cuisine_id1:cuisineArray2[0],cuisine_id2:cuisineArray2[1],cuisine_id3:cuisineArray2[2],cuisine_id4:cuisineArray2[3],cuisine_id5:cuisineArray2[4],cuisine_id6:cuisineArray2[5],cuisine_id7:cuisineArray2[6],cuisine_id8:cuisineArray2[7]};
axios(
{
method:'POST',
url:`http://localhost:7000/getCuisine`,
headers:{'Content-Type':'application/json'},
data:filterObj
}
)
.then(res=>
{
this.setState({restaurants:res.data.restaurants});
})
.catch(err=>console.log(err))
}
render()
{
const {restaurants}=this.state;
return(
<div>
<input type="checkbox" name="cuisines" id={"1"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > North Indian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"2"} onChange={(event) => this.handleCuisineChange("2")} />
<span className="checkbox-items" > south indian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"3"} onChange={(event) => this.handleCuisineChange("3")} />
<span className="checkbox-items" > chinese </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"4"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > fast food </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"5"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Street food </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"6"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > American </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"7"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Italian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"8"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Mexican </span> <div style={{display: "block"}}> </div>
</div>
)
} //render end