【发布时间】:2020-08-27 12:39:20
【问题描述】:
各位程序员,大家好,我是 React Native 新手,所以我会快速总结一下示例和代码,然后再继续。
我从 api 获取产品列表并将其存储在两个数组中:products[] 和 catalogue[]
目录数组用于存储从 api 接收到的所有项目。 products 数组是 Flatlist 用来显示数据的数组。应用过滤器时,应过滤产品中的项目,以便平面列表也更新屏幕上新过滤的数据。
现在这是我从 api 获取的所有对象数据中的一个简化对象。
Object {
"designNumber": "CHE-S-207 RW",
"id": 292187,
"imageUrl": "http://company.shop.org/images/shop/136/4.jpg",
"itemCategory": "BRACELET",
"itemStatus": "INSTOCK",
"itemType": "CHE",
"quantity": "1",
"rfidTag": "Item4",
"shopId": 136,
"skuNumber": "Item4",
}
我将从对象数据中用于过滤器的主要值是itemStatus、itemCategory 和itemType。
我在状态对象中使用这些变量来存储其中的值,我将使用多选选择器从过滤屏幕 UI 中选择这些值。
state = {
products: [],
catalogue: [],
itemStatus: "", //Binary values. Only one string value for this one
itemCategory: [], //Multiple values in array
itemType: [], //Multiple values in array
};
现在我们来谈谈主要交易。假设我已经使用过滤器屏幕 UI 为这些过滤器参数选择了某些值。例如,itemStatus: "AVAILABLE"、itemCategory: ["MENS", "WOMENS", "CORPORATE"] 和 itemType: ["COMMON","UNCOMMON", "SALE", "EXCLUSIVE"]
所以用外行的话来说,使用我为状态选择了可用的 UI,为类别选择了 3 个值,为类型选择了 4 个值。现在最后有一个应用过滤器按钮。这是我调用 filterProducts() 之类的函数的地方,它将采用这些多个参数并相应地过滤我的 Flatlist 项目。
请记住,catalogue[] 数组包含从 api 获取的全部数据,products[] 数组是在平面列表中显示的内容。因此,理想情况下,来自 filter 函数的任何新过滤数据都应该更新 products[] 数组,以便我认为也会在 Flatlist 上更新。
我的问题?我在堆栈和媒体上阅读的每篇文章总是只查看搜索栏搜索过滤器示例。基本上只接受1个过滤字符串然后过滤列表。
但是,如果我有多个参数要过滤,就像我试图实现的示例一样?如果您有 3 个参数,并且每个参数可以有多个值(4 个或更多)以在过滤中考虑,该怎么办。如何应用如此复杂的过滤级别,然后将过滤后的项目返回到我的 Flatlist?
<Button title="Apply Filter" onPress={() => this.filterProducts}/>
filterProducts = () => {
//Logic to take all the filter parameters and their selected values
this.state.products = if({/** No filters are applied */}){
return this.state.catalogue //Return original data
} else {
this.state.catalogue.filter({/** Apply complex filter logic here}).map(){
//return filtered items list
}
}
}
也许逻辑流程是这样的?除了我不知道如何过滤一个同时存在这么多过滤参数的列表。任何帮助将不胜感激。谢谢。
更新 1:根据 u/TommyLeong 的建议,我更新了我的代码。这是我的过滤器功能和逻辑的样子:
state = {
isFilterActive: false,
products: [],
catalogue: [],
itemStatus: "",
itemCategory: [],
itemType: [],
}
//Get data from the api
fetchProducts = aysnc () => {
//Make the api call and get the response
const data = await response.json();
this.setState({
products: data.data, //Originally show all the data from the api
catalogue: data.data, //Store all the data from the api
});
};
//Filter Function
filterProducts = () => {
console.log("function called", this.state.isFilterActive);
//Pack all filter data in one query object
let query = {
itemStatus: this.state.itemStatus,
itemCategory: this.state.itemCategory,
itemType: this.state.itemType,
};
console.log("Filter object", Object.entries(query));
if (this.state.isFilterActive) {
const filteredData = this.state.catalogue.filter(function (item) {
return Object.entries(query).every(([key, value]) =>
value.includes(item[key])
);
});
console.log("Result: Filtered Array", filteredData);
this.setState({ products: filteredData });
} else {
//Return original data is isFilterActive == false
this.setState({ products: this.state.catalogue });
}
};
render(){
return(
//Contains my views. My Filter screen has a bunch of pickers
//and a apply filter button
<DropDownPicker
label="Item Status"
multipleSelection={true} //More than one values can be selected
items={/*define my filter values for itemStatus here*/}
onChangeItem={(item) => {
this.setState({ itemStatus: item.value});
}
/>
<DropDownPicker
label="Item Category"
items={/*define my filter values for itemCategory here*/}
onChangeItem={(item) => {
//item here is an array of selected values
this.setState({ itemCategory: item});
}
/>
<DropDownPicker
label="Item Type"
multipleSelection={true} //More than one values can be selected
items={/*define my filter values for itemType here*/}
onChangeItem={(item) => {
//item here is an array of selected values
this.setState({ itemType: item });
}
/>
<Button
title="Apply Filter"
onPress={() => {
this.setState({ isFilterActive: true }, () =>
this.filterProducts()
);
}}
)
}
现在我的代码和逻辑已经很清楚了,让我们继续解决新问题。 过滤器功能中的过滤器逻辑 100% 有效! 但只有当所有 3 个过滤器属性都选择了某个值时
//my filter object in the function
let query = {
itemStatus: this.state.itemStatus,
itemCategory: this.state.itemCategory,
itemType: this.state.itemType,
};
案例 1:console.log 当所有 3 个过滤器类别都选择了一些值时:
Filter object Array [
Array [
"itemStatus",
"INSTOCK",
],
Array [
"itemCategory",
Array [
"MENS",
"WOMENS",
],
],
Array [
"itemType",
Array [
"COMMON",
"SALE"
],
],
]
Result: Filtered Array Array[
Object: {
//first item matching all 3 filter criteria
},
Object: {
//2nd item matching all 3 filter criteria
},
Object: {
//3rd item matching all 3 filter criteria
},
]
案例 2: 没有为 3 个过滤条件中的任何一个选择任何值时的 console.log。对于这种情况,我选择 itemType,即 itemType[] 为空白。
Filter object Array [
Array [
"itemStatus",
"INSTOCK",
],
Array [
"itemCategory",
Array [
"MENS",
"WOMENS",
],
],
Array [
"itemType",
Array [], //Array is blank here because no filter
//values were picked for itemType
],
]
Result: Filtered Array Array [] //No items returned to me, Flatlist becomes empty
我当然知道问题出在这个过滤器逻辑上,但我无法摆脱,为什么当 3 个条件之一存在未定义值时过滤器无法正常工作.. 最重要的是,再一次知道如何解决它:(
//Current filter Logic
if (this.state.isFilterActive) {
const filteredData = this.state.catalogue.filter(function (item) {
return Object.entries(query).every(([key, value]) =>
value.includes(item[key])
);
});
console.log("Result: Filtered Array", filteredData);
this.setState({ products: filteredData });
} else {
//Return original data is isFilterActive == false
this.setState({ products: this.state.catalogue });
}
【问题讨论】:
标签: javascript arrays react-native object react-native-flatlist