
[英]How to avoid rendering items with same id in the flatList multiple times?
[英]Flatlist adds multiple times the same items
我正在尝试使用 React Navigation 和 React Redux 制作一个小应用程序来计算卡路里。 目标是让用户在SearchBar
搜索一个项目,点击其中一个将他移动到Food
页面的食物项目,然后从该页面点击复选checkmark
以将食物添加到Flatlist
并将他发送回主屏幕( Diet
)。 我正在使用状态showList
在点击SearchBar
时显示Flatlist
,然后使用 React Navigation 导航并将params
发送到 Food 屏幕,然后使用 React Redux 更新全局状态foodList
并将该项目添加到主Flatlist
(在饮食屏幕)通过复选标记Button
,我还使用getDerivedStateFromprops
更新饮食屏幕中的状态foodList
。 问题是当我添加一个项目时,它会多次添加相同的项目,而当我添加一个新项目时,它会再次添加很多次相同的项目。 我曾经使用 React Navigation 将参数带回主屏幕,但我认为我可以通过使用 Redux 来解决这个问题,我错了,因为问题仍然存在。
主屏幕
class Diet extends Component {
constructor(props) {
super(props);
this.camera = null;
this.barcodeCodes = [];
this.state = {
showList: false,
data: [],
searchValue: "",
foodList: [],
foodName: null,
};
}
static getDerivedStateFromProps(props, state) {
if (props?.foodList) {
return {
foodList: [...state.foodList, ...props.foodList],
};
}
return null;
}
updateSearch = (value) => {
this.setState({ searchValue: value });
if (value.trim() !== "") {
axios
.get(
`https://api.edamam.com/api/food-database/v2/parser?ingr=${value}&app_id=2626c70d&app_key=0c0f87ae4e5437621363ecf8e7ea80ae&page=20`
)
.then((res) => {
this.setState({ data: res.data.hints });
})
.catch((error) => {
console.log(error.response.data);
});
}
};
return (
<SearchBar
platform={Platform.OS === "ios" ? "ios" : "android"}
placeholder="Search Food..."
onChangeText={this.updateSearch}
value={searchValue}
onFocus={() => this.setState({ showList: true })}
onCancel={() => this.setState({ showList: false })}
/>
{this.state.showList === true ? (
<View>
<FlatList
data={this.state.data.map((item) => item.food)}
renderItem={({ item }) => (
<ListItem>
<TouchableOpacity
onPress={() =>
{this.props.navigation.navigate("Food", {
id: item.foodId,
brand: item.brand,
title: item.label,
calories: item.nutrients.ENERC_KCAL,
protein: item.nutrients.PROCNT,
fat: item.nutrients.FAT,
carbs: item.nutrients.CHOCDF,
}),
this.setState({showList:false})
}
}
>
<View>
<Text>{item.label}</Text>
<Text>{item.brand}</Text>
</View>
</TouchableOpacity>
</ListItem>
)}
keyExtractor={(item) => item.foodId}
/>
) : (
<FlatList ///Main Flatlist
data={this.state.foodList}
renderItem={({item}) => (
<View>
<TouchableOpacity
onPress={() => {
this.props.navigation.navigate(
"FoodNotModifible",
{
title: item.foodName,
calories: item.calories,
carbs: item.carbs,
protein: item.protein,
fat: item.fat,
numberServings: item.numberServings,
servingSize: item.servingSize,
}
);
}}
>
<Text>{item.foodName}</Text>
<Text>
{item.calories}
</Text>
<MaterialIcons name="arrow-forward-ios" />
</TouchableOpacity>
</View>
)}
keyExtractor={item => item.foodId}
/>
);
}
}
function mapStateToProps(store){
return{
foodList: store.userState.foodList
};
}
export default connect(mapStateToProps)(Diet);
食物筛选
class Food extends Component {
constructor(props) {
super(props);
this.state = {
foodList: this.props.foodList,
}
}
submitFood = () => {
let foodList= this.state.foodList;
foodList.push({
foodId: this.props.route.params.foodId,
foodName: this.props.route.params.title,
calories: this.props.route.params.calories,
carbs: this.props.route.params.carbs,
protein: this.props.route.params.protein,
fat: this.props.route.params.fat,
});
this.props.updateFoodList(foodList);
this.props.navigation.navigate("Diet");
};
render() {
const { brand, title, calories, protein, carbs, fat, foodId } = this.props.route.params;
return (
<Container>
<Header>
<Left>
<Button transparent>
<Icon
name="arrow-back"
onPress={() => this.props.navigation.goBack()}
/>
</Button>
</Left>
<Body>
<Title>Add Food</Title>
</Body>
<Right>
<Button transparent>
<Icon
name="checkmark"
onPress={this.submitFood}
/>
</Button>
</Right>
</Header>
<View>
<Text>
{JSON.stringify(title)}
</Text>
<Text>
{JSON.stringify(brand)}
</Text>
</View>
Redux 函数
export const updateFoodList = (foodList) => {
return { type: ADD_FOOD, payload: foodList}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.