DIET (screen)
export class Diet extends Component { constructor(props) { super(props); this.state = { foodList: [], }; } render() { return ( <View> <List> <FlatList data={this.props.route?.params?.foodList} keyExtractor={(item, index) => item.key.toString()} renderItem={(data) => ( <ListItem> <Button> <Left> <Text>{data.item.foodName}</Text> </Left> <Right> <Text>{data.item.calories}</Text> <Icon name="arrow-forward" /> </Right> </Button> </ListItem> )} /> </List> </View>
FOODCREATE (screen)
export class FoodCreate extends Component { constructor(props) { super(props); this.state = { food: null, calories: null, foodList: [], }; } submitFood = (food, calories) => { this.setState( { foodList: [ ...this.state.foodList, { key: Math.random(), foodName: food, calories: calories, }, ], }, () => { this.props.navigation.navigate("Diet", { foodList: this.state.foodList, }); } ); }; render() { return ( <Container> <TextInput placeholder="Food Name" placeholderTextColor="white" style={styles.inptFood} value={this.state.food} onChangeText={(food) => this.setState({ food })} /> <TextInput placeholder="Calories" placeholderTextColor="white" style={styles.inptMacros} keyboardType="numeric" value={this.state.calories} maxLength={5} onChangeText={(calories) => this.setState({ calories })} /> <Button transparent> <Icon name="checkmark" style={{ fontSize: 25, color: "red" }} onPress={() => { this.submitFood(this.state.food, this.state.calories); }} /> </Button>
Hello everyone, I’m trying to make an app in which the user has to insert foodName
and calories
in the FoodCreate
screen and once he taps the checkmark
it will add the foodName
and calories
to the Flatlist
in the Diet
screen (when I launch Expo the first screen to appear is the Diet
screen). When I insert the first food item everything goes fine, but when I want to insert another one, the one I inserted before disappears and it shows only the one I just inserted. I don’t know if it’s a problem related with the Flatlist or React Navigation. But the Flatlist won’t keep the items I inserted.
Advertisement
Answer
The problem here is the way navigation works, Everytime you open the FoodCreate screen the the component is mounted again and the FoodList is reset, so the newly added one would be the only item there, you return this as a parameter to Diet screen which will show only one item.
Heres a the better way to do it.
Move the state management to Diet screen
class Diet extends Component { constructor(props) { super(props); this.state = { foodList: [], }; } // Use this to update state. static getDerivedStateFromProps(props, state) { if (props.route.params?.food) { return { foodList: [...state.foodList, props.route.params.food] }; } return null; }
And show the value in the state in the flatlist
<FlatList data={this.state.foodList} ...
Change submitFood like below to send only newly created item
submitFood = (food, calories) => { this.props.navigation.navigate("Diet", { food: { key: Math.random(), foodName: food, calories: calories, }, }); }
The easier way is to switch to functional components, you can refer the documentation here https://reactnavigation.org/docs/params/#passing-params-to-a-previous-screen